Merge pull request 'feature/applicationv2' (#57) from feature/applicationv2 into main
Reviewed-on: #57pull/61/head
commit
53c5c7b53a
|
|
@ -43,6 +43,7 @@ const convert = function (from, to, ofType) {
|
|||
mkdirSync(DEST)
|
||||
|
||||
readdirSync(SOURCE).forEach(file => {
|
||||
console.log(file)
|
||||
let originalSource = JSON.parse(readFileSync(join(SOURCE, file), {encoding: "utf8"}));
|
||||
let id = randomID();
|
||||
|
||||
|
|
@ -104,6 +105,10 @@ async function prepareDB() {
|
|||
convert("./src/packs/_source/liturgien-und-segnungen", "./src/packs/__source/liturgien", "Liturgy");
|
||||
convert("./src/packs/_source/wunden", "./src/packs/__source/wunden", "ActiveEffect");
|
||||
|
||||
convert("./src/packs/_source/kulturen", "./src/packs/__source/kulturen", "Culture");
|
||||
convert("./src/packs/_source/spezien", "./src/packs/__source/spezien", "Species");
|
||||
convert("./src/packs/_source/professionen", "./src/packs/__source/professionen", "Profession");
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
|
|
|
|||
74
src/main.mjs
74
src/main.mjs
|
|
@ -5,12 +5,12 @@ import {SkillDataModel} from "./module/data/skill.mjs";
|
|||
import {SpellDataModel} from "./module/data/spell.mjs";
|
||||
import {VornachteileDataModel} from "./module/data/vornachteile.mjs";
|
||||
import {Character} from "./module/documents/character.mjs";
|
||||
import {CharacterSheet} from "./module/sheets/characterSheet.mjs";
|
||||
import {VornachteilSheet} from "./module/sheets/vornachteilSheet.mjs";
|
||||
import CharacterSheet from "./module/sheets/characterSheet.mjs";
|
||||
import {AdvantageSheet} from "./module/sheets/advantageSheet.mjs";
|
||||
import {GroupDataModel} from "./module/data/group.mjs";
|
||||
import {GroupSheet} from "./module/sheets/groupSheet.mjs";
|
||||
import {EquipmentDataModel} from "./module/data/equipment.mjs";
|
||||
import {AusruestungSheet} from "./module/sheets/equipmentSheet.mjs";
|
||||
import {EquipmentSheet} from "./module/sheets/equipmentSheet.mjs";
|
||||
import {CreatureDataModel} from "./module/data/creature.mjs";
|
||||
import {CreatureSheet} from "./module/sheets/creatureSheet.mjs";
|
||||
import {LiturgySheet} from "./module/sheets/liturgySheet.mjs";
|
||||
|
|
@ -21,6 +21,12 @@ import {SpecialAbilitySheet} from "./module/sheets/specialAbilitySheet.mjs";
|
|||
import {ActiveEffectSheet} from "./module/sheets/ActiveEffectSheet.mjs";
|
||||
import {ActiveEffectDataModel} from "./module/data/activeeffect.mjs";
|
||||
import {Trefferzone, Wunde, Zonenruestung, Zonenwunde} from "./module/data/Trefferzone.js";
|
||||
import {ProfessionDataModel} from "./module/data/profession.mjs";
|
||||
import {SpeciesDataModel} from "./module/data/species.mjs";
|
||||
import {CultureDataModel} from "./module/data/culture.mjs";
|
||||
import {CultureSheet} from "./module/sheets/CultureSheet.mjs";
|
||||
import {SpeciesSheet} from "./module/sheets/SpeciesSheet.mjs";
|
||||
import {ProfessionSheet} from "./module/sheets/ProfessionSheet.mjs";
|
||||
|
||||
async function preloadHandlebarsTemplates() {
|
||||
return foundry.applications.handlebars.loadTemplates([
|
||||
|
|
@ -35,7 +41,6 @@ async function preloadHandlebarsTemplates() {
|
|||
'systems/DSA_4-1/templates/ui/partial-sf-button.hbs',
|
||||
'systems/DSA_4-1/templates/ui/partial-action-button.hbs',
|
||||
'systems/DSA_4-1/templates/ui/partial-equipment-button.hbs',
|
||||
'systems/DSA_4-1/templates/ui/partial-equipment-group-button.hbs',
|
||||
'systems/DSA_4-1/templates/ui/partial-array-editor.hbs',
|
||||
'systems/DSA_4-1/templates/dialog/modify-liturgy.hbs'
|
||||
]);
|
||||
|
|
@ -70,6 +75,9 @@ Hooks.once("init", () => {
|
|||
Blessing: BlessingDataModel,
|
||||
SpecialAbility: SpecialAbilityDataModel,
|
||||
ActiveEffect: ActiveEffectDataModel,
|
||||
Profession: ProfessionDataModel,
|
||||
Spezies: SpeciesDataModel,
|
||||
Kultur: CultureDataModel,
|
||||
}
|
||||
|
||||
CONFIG.Combat.initiative = {
|
||||
|
|
@ -94,8 +102,6 @@ Hooks.once("init", () => {
|
|||
makeDefault: true,
|
||||
label: 'DSA41.GroupLabel.Item'
|
||||
})
|
||||
|
||||
// Register sheet application classes
|
||||
foundry.documents.collections.Items.registerSheet('dsa41.skill', SkillSheet, {
|
||||
types: ["Skill"],
|
||||
makeDefault: true,
|
||||
|
|
@ -106,33 +112,58 @@ Hooks.once("init", () => {
|
|||
makeDefault: true,
|
||||
label: 'DSA41.SpellLabels.Item',
|
||||
});
|
||||
foundry.documents.collections.Items.registerSheet('dsa41.advantage', VornachteilSheet, {
|
||||
foundry.documents.collections.Items.registerSheet('dsa41.advantage', AdvantageSheet, {
|
||||
types: ["Advantage"],
|
||||
makeDefault: true,
|
||||
label: 'DSA41.VornachteilLabels.Item'
|
||||
})
|
||||
foundry.documents.collections.Items.registerSheet('dsa41.equipment', AusruestungSheet, {
|
||||
foundry.documents.collections.Items.registerSheet('dsa41.equipment', EquipmentSheet, {
|
||||
types: ["Equipment"],
|
||||
makeDefault: false,
|
||||
label: 'DSA41.AusruestungLabels.Item'
|
||||
})
|
||||
foundry.documents.collections.Items.registerSheet('dsa41.liturgy', LiturgySheet, {
|
||||
types: ["SpecialAbility"],
|
||||
makeDefault: true,
|
||||
label: 'DSA41.SpecialAbilityLabels.Item'
|
||||
})
|
||||
foundry.documents.collections.Items.registerSheet('dsa41.specialAbility', SpecialAbilitySheet, {
|
||||
types: ["Liturgy"],
|
||||
makeDefault: true,
|
||||
label: 'DSA41.LiturgyLabels.Item'
|
||||
})
|
||||
|
||||
foundry.documents.collections.Items.registerSheet('dsa41.specialAbility', SpecialAbilitySheet, {
|
||||
types: ["SpecialAbility"],
|
||||
makeDefault: true,
|
||||
label: 'DSA41.SpecialAbilityLabels.Item'
|
||||
})
|
||||
foundry.documents.collections.Items.registerSheet('dsa41.activeEffect', ActiveEffectSheet, {
|
||||
types: ['ActiveEffect'],
|
||||
makeDefault: true,
|
||||
label: 'DSA41.ActiveEffectLabels.ActiveFfect'
|
||||
label: 'DSA41.ActiveEffectLabels.ActiveEffect'
|
||||
})
|
||||
foundry.documents.collections.Items.registerSheet('dsa41.culture', CultureSheet, {
|
||||
types: ['Culture'],
|
||||
makeDefault: true,
|
||||
label: 'DSA41.CultureLabels.Culture'
|
||||
})
|
||||
foundry.documents.collections.Items.registerSheet('dsa41.spezien', SpeciesSheet, {
|
||||
types: ['Species'],
|
||||
makeDefault: true,
|
||||
label: 'DSA41.SpeciesLabels.Species'
|
||||
})
|
||||
foundry.documents.collections.Items.registerSheet('dsa41.profession', ProfessionSheet, {
|
||||
types: ['Profession'],
|
||||
makeDefault: true,
|
||||
label: 'DSA41.ProfessionLabels.Profession'
|
||||
})
|
||||
|
||||
game.settings.register('DSA_4-1', 'optional_colorfuldice', {
|
||||
name: "Optional: Farbige Würfel nach Paramanthus",
|
||||
hint: "Färbt die Würfel je nach Attribut ein",
|
||||
scope: "client",
|
||||
config: true,
|
||||
type: Boolean,
|
||||
default: false,
|
||||
onChange: value => {
|
||||
},
|
||||
requiresReload: false
|
||||
})
|
||||
game.settings.register('DSA_4-1', 'optional_trefferzonen', {
|
||||
name: "Optional: Trefferzonen",
|
||||
hint: "Ersetzt das Wundensystem aus dem BRW durch das Trefferzonensystem aus WdH",
|
||||
|
|
@ -144,7 +175,6 @@ Hooks.once("init", () => {
|
|||
},
|
||||
requiresReload: true
|
||||
})
|
||||
|
||||
game.settings.register('DSA_4-1', 'optional_ruestungzonen', {
|
||||
name: "Optional: Zonenrüstung",
|
||||
hint: "Ersetzt das Rüstungssystem aus dem BRW durch das Zonenrüstungssystem aus WdH",
|
||||
|
|
@ -156,7 +186,6 @@ Hooks.once("init", () => {
|
|||
},
|
||||
requiresReload: true
|
||||
})
|
||||
|
||||
game.settings.register('DSA_4-1', 'optional_ausdauer', {
|
||||
name: "Optional: Ausdauerregeln",
|
||||
hint: "Aktiviert Regeln für das Spiel mit Ausdauer",
|
||||
|
|
@ -168,7 +197,6 @@ Hooks.once("init", () => {
|
|||
},
|
||||
requiresReload: true
|
||||
})
|
||||
|
||||
game.settings.register('DSA_4-1', 'optional_distanzklassen', {
|
||||
name: "Optional: Distanzklassen",
|
||||
hint: "Aktiviert Regeln für das Spiel mit Distanzklassen",
|
||||
|
|
@ -184,16 +212,6 @@ Hooks.once("init", () => {
|
|||
return preloadHandlebarsTemplates();
|
||||
})
|
||||
|
||||
Hooks.on('dropActorSheetData', (actor, sheet, data) => {
|
||||
if (data.uuid) {
|
||||
if (actor.type === "character") {
|
||||
return CharacterSheet.onDroppedData(actor, sheet, data);
|
||||
} else {
|
||||
return GroupSheet.onDroppedData(actor, sheet, data);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Hooks.once("ready", async function () {
|
||||
// Wait to register hotbar drop hook on ready so that modules could register earlier if they want to
|
||||
Hooks.on("hotbarDrop", (bar, data, slot) => {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import {Equipment} from "../documents/equipment.mjs";
|
||||
|
||||
const {
|
||||
SchemaField,
|
||||
NumberField,
|
||||
StringField,
|
||||
HTMLField,
|
||||
EmbeddedDocumentField,
|
||||
DocumentIdField,
|
||||
ArrayField,
|
||||
ForeignDocumentField
|
||||
} = foundry.data.fields;
|
||||
|
||||
export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel {
|
||||
|
|
@ -29,6 +29,8 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel {
|
|||
familie: new HTMLField(),
|
||||
titel: new StringField(),
|
||||
stand: new StringField(),
|
||||
verbindungen: new HTMLField(),
|
||||
notizen: new HTMLField(),
|
||||
}),
|
||||
setEquipped: new NumberField({required: true, initial: 0, max: 3, integer: true}),
|
||||
ini: new SchemaField({
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
import BaseItem from "./base-item.mjs";
|
||||
|
||||
const {BooleanField, StringField, HTMLField} = foundry.data.fields;
|
||||
|
||||
export class CultureDataModel extends BaseItem {
|
||||
|
||||
static defineSchema() {
|
||||
return {
|
||||
description: new HTMLField(),
|
||||
variant: new StringField(),
|
||||
feminineDemonym: new StringField(),
|
||||
masculineDemonym: new StringField()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
import BaseItem from "./base-item.mjs";
|
||||
import {Equipment} from "../documents/equipment.mjs";
|
||||
|
||||
const {
|
||||
ArrayField, NumberField, StringField, HTMLField
|
||||
ArrayField, EmbeddedCollectionField, SchemaField, NumberField, StringField, HTMLField
|
||||
} = foundry.data.fields;
|
||||
|
||||
export class EquipmentDataModel extends BaseItem {
|
||||
|
|
@ -34,9 +35,25 @@ export class EquipmentDataModel extends BaseItem {
|
|||
rangedAttackDamage: new StringField(),
|
||||
rangedReloadTime: new NumberField({required: false}),
|
||||
|
||||
armorValue: new NumberField({required: false}),
|
||||
armorValue: new SchemaField({
|
||||
total: new NumberField({required: true, initial: 0}),
|
||||
armlinks: new NumberField({required: true, initial: 0}),
|
||||
beinlinks: new NumberField({required: true, initial: 0}),
|
||||
armrechts: new NumberField({required: true, initial: 0}),
|
||||
beinrechts: new NumberField({required: true, initial: 0}),
|
||||
ruecken: new NumberField({required: true, initial: 0}),
|
||||
bauch: new NumberField({required: true, initial: 0}),
|
||||
brust: new NumberField({required: true, initial: 0}),
|
||||
kopf: new NumberField({required: true, initial: 0}),
|
||||
}, {required: false}),
|
||||
armorHandicap: new NumberField({required: false}),
|
||||
|
||||
ammunition: new SchemaField({
|
||||
max: new NumberField({required: true, initial: 1}),
|
||||
count: new NumberField({required: true, initial: 1}),
|
||||
}, {required: false}),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ export class GroupDataModel extends foundry.abstract.TypeDataModel {
|
|||
quantity: new NumberField(),
|
||||
item: new DocumentIdField(Item)
|
||||
}),
|
||||
groupId: new DocumentIdField(Actor),
|
||||
characters: new ArrayField(
|
||||
new DocumentIdField(Actor)
|
||||
),
|
||||
|
|
@ -25,4 +26,13 @@ export class GroupDataModel extends foundry.abstract.TypeDataModel {
|
|||
}
|
||||
}
|
||||
|
||||
_onCreate(data, options, userId) {
|
||||
super._onCreate(data, options, userId);
|
||||
Folder.implementation.createDocuments([{name: data.name, type: "Actor"}]).then((
|
||||
folder
|
||||
) => {
|
||||
this.parent.update({"system.groupId": folder[0]._id});
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
import BaseItem from "./base-item.mjs";
|
||||
|
||||
const {BooleanField, StringField, HTMLField} = foundry.data.fields;
|
||||
|
||||
export class ProfessionDataModel extends BaseItem {
|
||||
|
||||
static defineSchema() {
|
||||
return {
|
||||
description: new HTMLField(),
|
||||
revealed: new BooleanField(),
|
||||
alias: new StringField(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -44,12 +44,89 @@ export class SkillDataModel extends BaseItem {
|
|||
}
|
||||
|
||||
/**
|
||||
* Handle clickable rolls.
|
||||
* @param {Event} event The originating click event
|
||||
* @private
|
||||
* Determines the values to consult for the given type of roll (normal: talent roll, attack: AT, parry: PA
|
||||
* @returns {{NORMAL: string, ATTACK: string, PARRY: string}}
|
||||
* @constructor
|
||||
*/
|
||||
async roll() {
|
||||
get SKILL_MODE() {
|
||||
return {
|
||||
NORMAL: "NORMAL",
|
||||
ATTACK: "ATTACK",
|
||||
PARRY: "PARRY",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param rollMode {["publicroll","gmroll"] }
|
||||
* @param mode
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async roll(rollMode = null, mode = this.SKILL_MODE.NORMAL) {
|
||||
|
||||
|
||||
|
||||
rollMode = rollMode ?? game.settings.get('core', 'rollMode');
|
||||
|
||||
switch (mode) {
|
||||
case this.SKILL_MODE.NORMAL:
|
||||
return this.#talentRoll(rollMode)
|
||||
case this.SKILL_MODE.ATTACK:
|
||||
case this.SKILL_MODE.PARRY:
|
||||
return this.#combatRoll(rollMode, mode)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async #combatRoll(rollMode, mode) {
|
||||
const owner = this.parent.parent
|
||||
const rollData = owner.getRollData()
|
||||
|
||||
let targetNumber = 0
|
||||
|
||||
if (mode === this.SKILL_MODE.ATTACK) {
|
||||
targetNumber = this.at + owner.system.at.basis
|
||||
} else {
|
||||
targetNumber = this.pa + owner.system.pa.basis
|
||||
}
|
||||
|
||||
let roll1 = new Roll(`1d20cs<${targetNumber}`, owner.getRollData());
|
||||
|
||||
let evaluated1 = (await roll1.evaluate())
|
||||
|
||||
const rolledValue = evaluated1.terms[0].results[0].result
|
||||
|
||||
if (rolledValue === 1 || rolledValue === 20) { // TODO: Modify this target
|
||||
// fill with actual evaluation (targetNumber should be reduced by X and roll against that again)
|
||||
}
|
||||
|
||||
let message = ""
|
||||
if (mode === this.SKILL_MODE.ATTACK) {
|
||||
if (rolledValue <= targetNumber) {
|
||||
message = `Würde treffen [${rolledValue}]`
|
||||
} else {
|
||||
message = `Verfehlt [${rolledValue}]`
|
||||
}
|
||||
} else {
|
||||
if (rolledValue <= targetNumber) {
|
||||
message = `Würde parrieren [${rolledValue}]`
|
||||
} else {
|
||||
message = `Verfehlt die parade [${rolledValue}]`
|
||||
}
|
||||
}
|
||||
|
||||
evaluated1.toMessage({
|
||||
speaker: ChatMessage.getSpeaker({actor: owner}),
|
||||
flavor: message,
|
||||
rollMode,
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
async #talentRoll(rollMode) {
|
||||
const owner = this.parent.parent
|
||||
|
||||
let roll1 = new Roll("3d20", owner.getRollData());
|
||||
|
||||
let evaluated1 = (await roll1.evaluate())
|
||||
|
|
@ -63,13 +140,13 @@ export class SkillDataModel extends BaseItem {
|
|||
evaluated1.toMessage({
|
||||
speaker: ChatMessage.getSpeaker({actor: owner}),
|
||||
flavor: ` ${dsaDieRollEvaluated.meisterlich ? 'Meisterlich geschafft' : 'Geschafft'} mit ${dsaDieRollEvaluated.tap} Punkten übrig`,
|
||||
rollMode: game.settings.get('core', 'rollMode'),
|
||||
rollMode,
|
||||
})
|
||||
} else { // misserfolg
|
||||
evaluated1.toMessage({
|
||||
speaker: ChatMessage.getSpeaker({actor: owner}),
|
||||
flavor: ` ${dsaDieRollEvaluated.meisterlich ? 'Gepatzt' : ''} mit ${Math.abs(dsaDieRollEvaluated.tap)} Punkten daneben`,
|
||||
rollMode: game.settings.get('core', 'rollMode'),
|
||||
rollMode,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
import BaseItem from "./base-item.mjs";
|
||||
|
||||
const {BooleanField, NumberField, StringField, HTMLField} = foundry.data.fields;
|
||||
|
||||
export class SpeciesDataModel extends BaseItem {
|
||||
|
||||
static defineSchema() {
|
||||
return {
|
||||
description: new HTMLField(),
|
||||
baseSpeed: new NumberField({required: true, initial: 6, integer: true}),
|
||||
feminineDemonym: new StringField(),
|
||||
masculineDemonym: new StringField(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import {importCharacter} from "../xml-import/xml-import.mjs";
|
||||
import {LiturgyData} from "../data/miracle/liturgydata.mjs";
|
||||
import {Zonenruestung, Zonenwunde} from "../data/Trefferzone.js";
|
||||
import {Zonenruestung, Zonenwunde, Wunde} from "../data/Trefferzone.js";
|
||||
import {PlayerCharacterDataModel} from "../data/character.mjs";
|
||||
|
||||
export class Character extends Actor {
|
||||
|
||||
|
|
@ -91,7 +92,7 @@ export class Character extends Actor {
|
|||
systemData.mr.basis = Math.round((mu + kl + ko) / 5)
|
||||
systemData.mr.aktuell = systemData.mr.basis + (systemData.mr.mod ?? 0);
|
||||
systemData.gs.basis = 6;
|
||||
systemData.gs.aktuell = systemData.gs.basis + (systemData.gs.mod ?? 0); // TOOD: get GS from species
|
||||
systemData.gs.aktuell = systemData.gs.basis + (systemData.gs.mod ?? 0); // TOOD: get GS from spezien
|
||||
|
||||
|
||||
if (game.settings.get("DSA_4-1", "optional_ruestungzonen")) {
|
||||
|
|
@ -116,6 +117,7 @@ export class Character extends Actor {
|
|||
systemData.wunden.kopf = 0;
|
||||
systemData.wunden.brust = 0;
|
||||
systemData.wunden.bauch = 0;
|
||||
systemData.wunden.ruecken = 0;
|
||||
systemData.wunden.armlinks = 0;
|
||||
systemData.wunden.armrechts = 0;
|
||||
systemData.wunden.beinlinks = 0;
|
||||
|
|
@ -127,73 +129,40 @@ export class Character extends Actor {
|
|||
// map current set to RS and BE
|
||||
|
||||
const ausruestung = systemData.heldenausruestung[systemData.setEquipped];
|
||||
if (ausruestung) {
|
||||
if (ausruestung.brust) {
|
||||
systemData.be += systemData.parent.items.get(ausruestung.brust).system.armorHandicap ?? 0
|
||||
if (game.settings.get("DSA_4-1", "optional_ruestungzonen")) {
|
||||
systemData.rs.brust = systemData.parent.items.get(ausruestung.brust).system.armorValue ?? 0
|
||||
} else {
|
||||
systemData.rs += systemData.parent.items.get(ausruestung.brust).system.armorValue ?? 0
|
||||
}
|
||||
}
|
||||
if (ausruestung.bauch) {
|
||||
systemData.be += systemData.parent.items.get(ausruestung.bauch).system.armorHandicap ?? 0
|
||||
if (game.settings.get("DSA_4-1", "optional_ruestungzonen")) {
|
||||
systemData.rs.bauch = systemData.parent.items.get(ausruestung.bauch).system.armorValue ?? 0
|
||||
} else {
|
||||
systemData.rs += systemData.parent.items.get(ausruestung.bauch).system.armorValue ?? 0
|
||||
}
|
||||
}
|
||||
if (ausruestung.ruecken) {
|
||||
systemData.be += systemData.parent.items.get(ausruestung.ruecken).system.armorHandicap ?? 0
|
||||
if (game.settings.get("DSA_4-1", "optional_ruestungzonen")) {
|
||||
// ruecken is not a valid trefferzone
|
||||
} else {
|
||||
systemData.rs += systemData.parent.items.get(ausruestung.ruecken).system.armorValue ?? 0
|
||||
}
|
||||
}
|
||||
if (ausruestung.armlinks) {
|
||||
systemData.be += systemData.parent.items.get(ausruestung.armlinks).system.armorHandicap ?? 0
|
||||
if (game.settings.get("DSA_4-1", "optional_ruestungzonen")) {
|
||||
systemData.rs.armlinks = systemData.parent.items.get(ausruestung.armlinks).system.armorValue ?? 0
|
||||
} else {
|
||||
systemData.rs += systemData.parent.items.get(ausruestung.armlinks).system.armorValue ?? 0
|
||||
}
|
||||
}
|
||||
if (ausruestung.armrechts) {
|
||||
systemData.be += systemData.parent.items.get(ausruestung.armrechts).system.armorHandicap ?? 0
|
||||
if (game.settings.get("DSA_4-1", "optional_ruestungzonen")) {
|
||||
systemData.rs.armrechts = systemData.parent.items.get(ausruestung.armrechts).system.armorValue ?? 0
|
||||
} else {
|
||||
systemData.rs += systemData.parent.items.get(ausruestung.armrechts).system.armorValue ?? 0
|
||||
}
|
||||
}
|
||||
if (ausruestung.beinlinks) {
|
||||
systemData.be += systemData.parent.items.get(ausruestung.beinlinks).system.armorHandicap ?? 0
|
||||
if (game.settings.get("DSA_4-1", "optional_ruestungzonen")) {
|
||||
systemData.rs.beinlinks = systemData.parent.items.get(ausruestung.beinlinks).system.armorValue ?? 0
|
||||
} else {
|
||||
systemData.rs += systemData.parent.items.get(ausruestung.beinlinks).system.armorValue ?? 0
|
||||
}
|
||||
}
|
||||
if (ausruestung.beinrechts) {
|
||||
systemData.be += systemData.parent.items.get(ausruestung.beinrechts).system.armorHandicap ?? 0
|
||||
if (game.settings.get("DSA_4-1", "optional_ruestungzonen")) {
|
||||
systemData.rs.beinrechts = systemData.parent.items.get(ausruestung.beinrechts).system.armorValue ?? 0
|
||||
} else {
|
||||
systemData.rs += systemData.parent.items.get(ausruestung.beinrechts).system.armorValue ?? 0
|
||||
}
|
||||
}
|
||||
if (ausruestung.kopf) {
|
||||
systemData.be += systemData.parent.items.get(ausruestung.kopf).system.armorHandicap ?? 0
|
||||
if (game.settings.get("DSA_4-1", "optional_ruestungzonen")) {
|
||||
systemData.rs.kopf = systemData.parent.items.get(ausruestung.kopf).system.armorValue ?? 0
|
||||
} else {
|
||||
systemData.rs += systemData.parent.items.get(ausruestung.kopf).system.armorValue ?? 0
|
||||
}
|
||||
}
|
||||
const zonesToCheck = [
|
||||
"brust",
|
||||
"bauch",
|
||||
"ruecken",
|
||||
"kopf",
|
||||
"armlinks",
|
||||
"armrechts",
|
||||
"beinlinks",
|
||||
"beinrechts"]
|
||||
|
||||
if (game.settings.get("DSA_4-1", "optional_ruestungzonen")) {
|
||||
systemData.rs.gesamt = 0
|
||||
systemData.rs.brust = 0
|
||||
systemData.rs.bauch = 0
|
||||
systemData.rs.ruecken = 0
|
||||
systemData.rs.kopf = 0
|
||||
systemData.rs.armlinks = 0
|
||||
systemData.rs.armrechts = 0
|
||||
systemData.rs.beinlinks = 0
|
||||
systemData.rs.beinrechts = 0
|
||||
} else {
|
||||
systemData.rs = 0
|
||||
}
|
||||
|
||||
zonesToCheck.forEach((zone) => {
|
||||
systemData.be += systemData.parent.items.get(ausruestung[zone])?.system.armorHandicap ?? 0
|
||||
if (game.settings.get("DSA_4-1", "optional_ruestungzonen")) {
|
||||
zonesToCheck.forEach((itemZone) => {
|
||||
systemData.rs[itemZone] += systemData.parent.items.get(ausruestung[zone])?.system.armorValue[itemZone] ?? 0
|
||||
})
|
||||
} else {
|
||||
systemData.rs += systemData.parent.items.get(ausruestung[zone])?.system.armorValue.total ?? 0
|
||||
}
|
||||
})
|
||||
|
||||
systemData.kap.max = 0;
|
||||
|
||||
|
|
@ -223,14 +192,10 @@ export class Character extends Actor {
|
|||
|
||||
getRollData() {
|
||||
const data = super.getRollData();
|
||||
this.prepareDerivedData()
|
||||
|
||||
if (this.type !== 'character' && this.type !== 'creature') return;
|
||||
|
||||
if (data.attribute) {
|
||||
for (let [k, v] of Object.entries(data.attribute)) {
|
||||
data[k] = foundry.utils.deepClone(v);
|
||||
}
|
||||
}
|
||||
|
||||
// move sonderfertigkeiten into data, if it isn't in data the actor doesn't have that sonderfertigkeit
|
||||
|
||||
|
|
@ -245,6 +210,48 @@ export class Character extends Actor {
|
|||
return data;
|
||||
}
|
||||
|
||||
|
||||
findEquipmentOnSlot(slot, setNumber) {
|
||||
return this.items.get(this.system.heldenausruestung[setNumber ?? this.system.setEquipped]?.[slot])
|
||||
}
|
||||
|
||||
getEquipmentSetUpdateObject() {
|
||||
const updateObject = {}
|
||||
Array.from(this.system.heldenausruestung).forEach((equipmentSet, index) => {
|
||||
updateObject[`system.heldenausruestung.${index}.links`] = equipmentSet.links;
|
||||
updateObject[`system.heldenausruestung.${index}.rechts`] = equipmentSet.rechts;
|
||||
updateObject[`system.heldenausruestung.${index}.brust`] = equipmentSet.brust;
|
||||
updateObject[`system.heldenausruestung.${index}.bauch`] = equipmentSet.bauch;
|
||||
updateObject[`system.heldenausruestung.${index}.ruecken`] = equipmentSet.ruecken;
|
||||
updateObject[`system.heldenausruestung.${index}.kopf`] = equipmentSet.kopf;
|
||||
updateObject[`system.heldenausruestung.${index}.fernkampf`] = equipmentSet.fernkampf;
|
||||
updateObject[`system.heldenausruestung.${index}.munition`] = equipmentSet.munition;
|
||||
updateObject[`system.heldenausruestung.${index}.armlinks`] = equipmentSet.armlinks;
|
||||
updateObject[`system.heldenausruestung.${index}.armrechts`] = equipmentSet.armrechts;
|
||||
updateObject[`system.heldenausruestung.${index}.beinlinks`] = equipmentSet.beinlinks;
|
||||
updateObject[`system.heldenausruestung.${index}.beinrechts`] = equipmentSet.beinrechts;
|
||||
|
||||
})
|
||||
return updateObject;
|
||||
}
|
||||
|
||||
|
||||
isWorn(itemId) {
|
||||
|
||||
const slots = PlayerCharacterDataModel.getSlots()
|
||||
const set = this.system.heldenausruestung[this.system.setEquipped]
|
||||
if (set) {
|
||||
for (const slot of slots) {
|
||||
const equipmentSlotId = set[slot]
|
||||
if (equipmentSlotId === itemId) {
|
||||
return slot
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param amount
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
export class Culture extends Item {
|
||||
/**
|
||||
* Augment the basic Item data model with additional dynamic data.
|
||||
*/
|
||||
prepareData() {
|
||||
super.prepareData();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
export class Profession extends Item {
|
||||
/**
|
||||
* Augment the basic Item data model with additional dynamic data.
|
||||
*/
|
||||
prepareData() {
|
||||
super.prepareData();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
export class Species extends Item {
|
||||
/**
|
||||
* Augment the basic Item data model with additional dynamic data.
|
||||
*/
|
||||
prepareData() {
|
||||
super.prepareData();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,44 +1,65 @@
|
|||
export class ActiveEffectSheet extends foundry.appv1.sheets.ItemSheet {
|
||||
/**@override */
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ['dsa41', 'sheet', 'activeeffect'],
|
||||
width: 520,
|
||||
height: 480
|
||||
});
|
||||
const {DocumentSheetV2, HandlebarsApplicationMixin} = foundry.applications.api
|
||||
|
||||
export class ActiveEffectSheet extends HandlebarsApplicationMixin(DocumentSheetV2) {
|
||||
|
||||
/** @inheritDoc */
|
||||
static DEFAULT_OPTIONS = {
|
||||
position: {width: 520, height: 480},
|
||||
classes: ['dsa41', 'sheet', 'item', 'activeeffect'],
|
||||
tag: 'form',
|
||||
form: {
|
||||
submitOnChange: true,
|
||||
closeOnSubmit: false,
|
||||
handler: ActiveEffectSheet.#onSubmitForm
|
||||
},
|
||||
actions: {
|
||||
openEffect: ActiveEffectSheet.#openEffect,
|
||||
editImage: DocumentSheetV2.DEFAULT_OPTIONS.actions.editImage,
|
||||
}
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
static PARTS = {
|
||||
form: {
|
||||
template: `systems/DSA_4-1/templates/item/activeeffect/main-sheet.hbs`
|
||||
},
|
||||
}
|
||||
|
||||
static async #openEffect(evt) {
|
||||
evt.preventDefault()
|
||||
const {id} = evt.srcElement.dataset
|
||||
const effect = await this.document.effects.get(id)
|
||||
effect.sheet.render(true)
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle form submission
|
||||
* @this {AdvantageSheet}
|
||||
* @param {SubmitEvent} event
|
||||
* @param {HTMLFormElement} form
|
||||
* @param {FormDataExtended} formData
|
||||
*/
|
||||
static async #onSubmitForm(event, form, formData) {
|
||||
event.preventDefault()
|
||||
|
||||
await this.document.update(formData.object) // Note: formData.object
|
||||
}
|
||||
|
||||
/** @override */
|
||||
get template() {
|
||||
return `systems/DSA_4-1/templates/item/item-activeeffect-sheet.hbs`;
|
||||
}
|
||||
async _prepareContext(options) {
|
||||
|
||||
/** @override */
|
||||
getData() {
|
||||
// Retrieve the data structure from the base sheet. You can inspect or log
|
||||
// the context variable to see the structure, but some key properties for
|
||||
// sheets are the actor object, the data object, whether or not it's
|
||||
// editable, the items array, and the effects array.
|
||||
const context = super.getData();
|
||||
const effects = context.document.getEmbeddedCollection("ActiveEffect").contents;
|
||||
const context = await super._prepareContext(options)
|
||||
context.system = context.document.system
|
||||
|
||||
const effects = context.document.getEmbeddedCollection("ActiveEffect").contents
|
||||
if (effects.length > 0) {
|
||||
context.effectId = effects[0]._id;
|
||||
context.effectId = effects[0]._id
|
||||
}
|
||||
|
||||
return context;
|
||||
context.name = context.document.name
|
||||
context.img = context.document.img
|
||||
context.notes = context.document.system.notes
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
// Everything below here is only needed if the sheet is editable
|
||||
if (!this.isEditable) return;
|
||||
|
||||
html.on('click', '.editEffects', (evt) => {
|
||||
const {id} = evt.currentTarget.dataset;
|
||||
const effect = this.object.effects.get(id);
|
||||
effect.sheet.render(true);
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
const {DocumentSheetV2, HandlebarsApplicationMixin} = foundry.applications.api
|
||||
|
||||
export class CultureSheet extends HandlebarsApplicationMixin(DocumentSheetV2) {
|
||||
|
||||
/** @inheritDoc */
|
||||
static DEFAULT_OPTIONS = {
|
||||
position: {width: 520, height: 480},
|
||||
classes: ['dsa41', 'sheet', 'item', 'culture'],
|
||||
tag: 'form',
|
||||
form: {
|
||||
submitOnChange: true,
|
||||
closeOnSubmit: false,
|
||||
handler: CultureSheet.#onSubmitForm
|
||||
},
|
||||
actions: {
|
||||
editImage: DocumentSheetV2.DEFAULT_OPTIONS.actions.editImage,
|
||||
}
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
static PARTS = {
|
||||
form: {
|
||||
template: `systems/DSA_4-1/templates/item/culture-sheet.hbs`
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle form submission
|
||||
* @this {CultureSheet}
|
||||
* @param {SubmitEvent} event
|
||||
* @param {HTMLFormElement} form
|
||||
* @param {FormDataExtended} formData
|
||||
*/
|
||||
static async #onSubmitForm(event, form, formData) {
|
||||
event.preventDefault()
|
||||
|
||||
await this.document.update(formData.object) // Note: formData.object
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async _prepareContext(options) {
|
||||
|
||||
const context = await super._prepareContext(options)
|
||||
context.system = context.document.system
|
||||
|
||||
context.name = context.document.name
|
||||
context.img = context.document.img
|
||||
context.description = context.document.system.description
|
||||
context.masculineDemonym = context.document.system.masculineDemonym
|
||||
context.feminineDemonym = context.document.system.feminineDemonym
|
||||
|
||||
return context
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
const {DocumentSheetV2, HandlebarsApplicationMixin} = foundry.applications.api
|
||||
|
||||
export class ProfessionSheet extends HandlebarsApplicationMixin(DocumentSheetV2) {
|
||||
|
||||
/** @inheritDoc */
|
||||
static DEFAULT_OPTIONS = {
|
||||
position: {width: 520, height: 480},
|
||||
classes: ['dsa41', 'sheet', 'item', 'species'],
|
||||
tag: 'form',
|
||||
form: {
|
||||
submitOnChange: true,
|
||||
closeOnSubmit: false,
|
||||
handler: ProfessionSheet.#onSubmitForm
|
||||
},
|
||||
actions: {
|
||||
editImage: DocumentSheetV2.DEFAULT_OPTIONS.actions.editImage,
|
||||
}
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
static PARTS = {
|
||||
form: {
|
||||
template: `systems/DSA_4-1/templates/item/profession-sheet.hbs`
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle form submission
|
||||
* @this {ProfessionSheet}
|
||||
* @param {SubmitEvent} event
|
||||
* @param {HTMLFormElement} form
|
||||
* @param {FormDataExtended} formData
|
||||
*/
|
||||
static async #onSubmitForm(event, form, formData) {
|
||||
event.preventDefault()
|
||||
|
||||
await this.document.update(formData.object) // Note: formData.object
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async _prepareContext(options) {
|
||||
|
||||
const context = await super._prepareContext(options)
|
||||
context.system = context.document.system
|
||||
|
||||
context.name = context.document.name
|
||||
context.img = context.document.img
|
||||
context.description = context.document.system.description
|
||||
context.alias = context.document.system.alias
|
||||
context.isOwner = context.document.owner
|
||||
context.revealed = context.document.system.revealed
|
||||
|
||||
return context
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
const {DocumentSheetV2, HandlebarsApplicationMixin} = foundry.applications.api
|
||||
|
||||
export class SpeciesSheet extends HandlebarsApplicationMixin(DocumentSheetV2) {
|
||||
|
||||
/** @inheritDoc */
|
||||
static DEFAULT_OPTIONS = {
|
||||
position: {width: 520, height: 480},
|
||||
classes: ['dsa41', 'sheet', 'item', 'species'],
|
||||
tag: 'form',
|
||||
form: {
|
||||
submitOnChange: true,
|
||||
closeOnSubmit: false,
|
||||
handler: SpeciesSheet.#onSubmitForm
|
||||
},
|
||||
actions: {
|
||||
editImage: DocumentSheetV2.DEFAULT_OPTIONS.actions.editImage,
|
||||
}
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
static PARTS = {
|
||||
form: {
|
||||
template: `systems/DSA_4-1/templates/item/species-sheet.hbs`
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle form submission
|
||||
* @this {SpeciesSheet}
|
||||
* @param {SubmitEvent} event
|
||||
* @param {HTMLFormElement} form
|
||||
* @param {FormDataExtended} formData
|
||||
*/
|
||||
static async #onSubmitForm(event, form, formData) {
|
||||
event.preventDefault()
|
||||
|
||||
await this.document.update(formData.object) // Note: formData.object
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async _prepareContext(options) {
|
||||
|
||||
const context = await super._prepareContext(options)
|
||||
context.system = context.document.system
|
||||
|
||||
context.name = context.document.name
|
||||
context.img = context.document.img
|
||||
context.description = context.document.system.description
|
||||
context.baseSpeed = context.document.baseSpeed
|
||||
context.masculineDemonym = context.document.system.masculineDemonym
|
||||
context.feminineDemonym = context.document.system.feminineDemonym
|
||||
|
||||
return context
|
||||
}
|
||||
}
|
||||
|
|
@ -68,21 +68,21 @@ export class ActionManager {
|
|||
type: ActionManager.ATTACK,
|
||||
cost: ActionManager.REGULAR,
|
||||
source: ActionManager.DEFAULT,
|
||||
eval: () => true
|
||||
eval: () => this.#hatWaffeinHand()
|
||||
},
|
||||
{
|
||||
name: "Schnellschuss",
|
||||
type: ActionManager.INTERACTION,
|
||||
cost: ActionManager.CONTINUING,
|
||||
source: ActionManager.DEFAULT,
|
||||
eval: () => true
|
||||
eval: () => this.#hatFernkampfWaffeinHand()
|
||||
},
|
||||
{
|
||||
name: "Schnellschuss (Scharfschütze)",
|
||||
type: ActionManager.INTERACTION,
|
||||
cost: ActionManager.CONTINUING,
|
||||
source: ActionManager.SF,
|
||||
eval: () => this.#hatSonderfertigkeit("Scharfschütze")
|
||||
eval: () => this.#hatFernkampfWaffeinHand() && this.#hatSonderfertigkeit("Scharfschütze")
|
||||
},
|
||||
{
|
||||
name: "Abwehraktion",
|
||||
|
|
@ -110,7 +110,14 @@ export class ActionManager {
|
|||
type: ActionManager.ATTACK,
|
||||
cost: ActionManager.REGULAR,
|
||||
source: ActionManager.SF,
|
||||
eval: () => this.#hatSonderfertigkeit("Finte")
|
||||
eval: () => this.#hatFernkampfWaffeinHand() && this.#hatSonderfertigkeit("Finte")
|
||||
},
|
||||
{
|
||||
name: "Wuchtschlag",
|
||||
type: ActionManager.ATTACK,
|
||||
cost: ActionManager.REGULAR,
|
||||
source: ActionManager.DEFAULT,
|
||||
eval: () => true
|
||||
},
|
||||
{
|
||||
name: "Wuchtschlag",
|
||||
|
|
@ -162,21 +169,21 @@ export class ActionManager {
|
|||
type: ActionManager.INTERACTION,
|
||||
cost: ActionManager.CONTINUING,
|
||||
source: ActionManager.SF,
|
||||
eval: () => this.#hatSonderfertigkeit("Schnellladen (Bogen)")
|
||||
eval: () => this.#hatMunition() && this.#hatFernkampfWaffeinHand("Bogen") && this.#hatSonderfertigkeit("Schnellladen (Bogen)")
|
||||
},
|
||||
{
|
||||
name: "Schnellladen (Armbrust)",
|
||||
type: ActionManager.INTERACTION,
|
||||
cost: ActionManager.CONTINUING,
|
||||
source: ActionManager.SF,
|
||||
eval: () => this.#hatSonderfertigkeit("Schnellladen (Armbrust)")
|
||||
eval: () => this.#hatMunition() && this.#hatFernkampfWaffeinHand("Armbrust") && this.#hatSonderfertigkeit("Schnellladen (Armbrust)")
|
||||
},
|
||||
{
|
||||
name: "Nachladen",
|
||||
type: ActionManager.INTERACTION,
|
||||
cost: ActionManager.CONTINUING,
|
||||
source: ActionManager.DEFAULT,
|
||||
eval: () => true
|
||||
eval: () => this.#hatMunition()
|
||||
},
|
||||
{
|
||||
name: "Talenteinsatz",
|
||||
|
|
@ -201,6 +208,23 @@ export class ActionManager {
|
|||
}
|
||||
]
|
||||
|
||||
|
||||
#hatWaffeinHand() {
|
||||
const item = this.actor.findEquipmentOnSlot("links") ?? this.actor.findEquipmentOnSlot("rechts")
|
||||
return item
|
||||
}
|
||||
|
||||
#hatMunition() {
|
||||
const item = this.actor.findEquipmentOnSlot("munition")
|
||||
const weapon = this.actor.findEquipmentOnSlot("fernkampf")
|
||||
return item
|
||||
}
|
||||
|
||||
#hatFernkampfWaffeinHand(art) {
|
||||
const item = this.actor.findEquipmentOnSlot("fernkampf")
|
||||
return item
|
||||
}
|
||||
|
||||
#hatSonderfertigkeitBeginnendMit(name) {
|
||||
return this.actor.system.sonderfertigkeiten?.find(p => p.name.startsWith(name)) != null
|
||||
}
|
||||
|
|
@ -211,8 +235,6 @@ export class ActionManager {
|
|||
|
||||
evaluate() {
|
||||
let actionArray = [...this.#freeActions, ...this.#regularActions, ...this.#continuingActions]
|
||||
|
||||
|
||||
return actionArray.filter(action => action.eval());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
const {DocumentSheetV2, HandlebarsApplicationMixin} = foundry.applications.api
|
||||
|
||||
export class AdvantageSheet extends HandlebarsApplicationMixin(DocumentSheetV2) {
|
||||
|
||||
/** @inheritDoc */
|
||||
static DEFAULT_OPTIONS = {
|
||||
position: {width: 520, height: 480},
|
||||
classes: ['dsa41', 'sheet', 'item', 'advantage'],
|
||||
tag: 'form',
|
||||
form: {
|
||||
submitOnChange: true,
|
||||
closeOnSubmit: false,
|
||||
handler: AdvantageSheet.#onSubmitForm
|
||||
}
|
||||
}
|
||||
|
||||
static TABS = {
|
||||
sheet: {
|
||||
tabs: [
|
||||
{id: 'advantage', group: 'sheet', label: 'Vorteil'},
|
||||
],
|
||||
initial: 'advantage'
|
||||
}
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
static PARTS = {
|
||||
form: {
|
||||
template: `systems/DSA_4-1/templates/item/advantage/main-sheet.hbs`
|
||||
},
|
||||
advantage: {
|
||||
template: `systems/DSA_4-1/templates/item/advantage/tab-advantage.hbs`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle form submission
|
||||
* @this {AdvantageSheet}
|
||||
* @param {SubmitEvent} event
|
||||
* @param {HTMLFormElement} form
|
||||
* @param {FormDataExtended} formData
|
||||
*/
|
||||
static async #onSubmitForm(event, form, formData) {
|
||||
event.preventDefault()
|
||||
|
||||
await this.document.update(formData.object) // Note: formData.object
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async _prepareContext(options) {
|
||||
const context = await super._prepareContext(options);
|
||||
const advantageData = context.document;
|
||||
|
||||
context.system = advantageData.system;
|
||||
context.flags = context.system.flags;
|
||||
context.hasChoices = context.system.auswahl.length > 0;
|
||||
context.choices = {}
|
||||
context.system.auswahl.forEach(a => {
|
||||
context.choices[a] = a
|
||||
})
|
||||
context.hasModality = context.system.value != null
|
||||
|
||||
return context;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
export default {
|
||||
_prepareContext: async (context, options, object) => {
|
||||
|
||||
const actorData = context.document
|
||||
context.system = actorData.system
|
||||
context.flags = actorData.flags
|
||||
context.derived = context.document.system
|
||||
context.originalName = actorData.name
|
||||
context.name = context.derived.name ?? actorData.name
|
||||
context.effects = actorData.effects ?? []
|
||||
context.advantages = []
|
||||
|
||||
actorData.itemTypes.Advantage.forEach((item) => {
|
||||
context.advantages.push({
|
||||
id: item._id,
|
||||
name: item.name,
|
||||
value: item.system.value,
|
||||
options: item.system.auswahl,
|
||||
description: item.system.description,
|
||||
isAdvantage: !item.system.nachteil,
|
||||
isDisadvantage: item.system.nachteil,
|
||||
isBadAttribute: item.system.schlechteEigenschaft
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
context.specialAbilities = []
|
||||
actorData.itemTypes.SpecialAbility.forEach((item) => {
|
||||
context.specialAbilities.push({
|
||||
id: item._id,
|
||||
name: item.name,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
return context
|
||||
},
|
||||
_onRender: (context, options, thisObject) => {
|
||||
new foundry.applications.ux.DragDrop.implementation({
|
||||
dropSelector: ".advantages, .special-abilities",
|
||||
permissions: {
|
||||
drop: thisObject._canDragDrop.bind(thisObject)
|
||||
},
|
||||
callbacks: {
|
||||
drop: thisObject._onDrop.bind(thisObject),
|
||||
}
|
||||
}).bind(thisObject.element);
|
||||
},
|
||||
_getTabConfig: (group) => {
|
||||
group.tabs.push({id: "advsf", group: "sheet", label: "Vorteile"})
|
||||
},
|
||||
template: `systems/DSA_4-1/templates/actor/character/tab-advsf.hbs`
|
||||
}
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
import {ActionManager} from "../actions/action-manager.mjs";
|
||||
|
||||
export default {
|
||||
_prepareContext: async (context, object) => {
|
||||
|
||||
const actorData = context.document
|
||||
context.system = actorData.system
|
||||
context.flags = actorData.flags
|
||||
context.derived = context.document.system
|
||||
context.originalName = actorData.name
|
||||
context.name = context.derived.name ?? actorData.name
|
||||
context.effects = actorData.effects ?? []
|
||||
|
||||
const findEquipmentOnSlot = (slot, setNumber, object) => {
|
||||
return object.items.get(object.system.heldenausruestung[setNumber]?.[slot])
|
||||
}
|
||||
|
||||
const am = new ActionManager(actorData)
|
||||
context.actions = am.evaluate()
|
||||
|
||||
|
||||
context.inidice = actorData.system.ini.wuerfel
|
||||
context.inivalue = actorData.system.ini.aktuell
|
||||
context.inimod = actorData.system.ini.mod
|
||||
|
||||
context.aupper = Math.min((actorData.system.aup.aktuell / actorData.system.aup.max) * 100, 100)
|
||||
context.lepper = Math.min((actorData.system.lep.aktuell / actorData.system.lep.max) * 100, 100)
|
||||
context.keper = Math.min((actorData.system.kap.aktuell / actorData.system.kap.max) * 100, 100)
|
||||
context.aspper = Math.min((actorData.system.asp.aktuell / actorData.system.asp.max) * 100, 100)
|
||||
context.lepcurrent = actorData.system.lep.aktuell ?? 0
|
||||
|
||||
context.aupcurrent = actorData.system.aup.aktuell ?? 0
|
||||
|
||||
const fernkampf = findEquipmentOnSlot("fernkampf", actorData.system.setEquipped, actorData)
|
||||
const links = findEquipmentOnSlot("links", actorData.system.setEquipped, actorData)
|
||||
const rechts = findEquipmentOnSlot("rechts", actorData.system.setEquipped, actorData)
|
||||
context.attacks = [];
|
||||
|
||||
if (fernkampf) {
|
||||
const fkitems = fernkampf.system.rangedSkills.map((skillInQuestion) => actorData.items.find(p => p.name === skillInQuestion))
|
||||
fkitems.forEach(async skill => {
|
||||
const obj = await skill
|
||||
context.attacks.push({
|
||||
name: obj.name,
|
||||
using: fernkampf.name,
|
||||
atroll: `1d20cs<${object.system.fk.aktuell + obj.system.at}`,
|
||||
at: `${object.system.fk.aktuell + obj.system.at}`,
|
||||
tproll: `${fernkampf.system.rangedAttackDamage}`, // TODO consider adding TP/KK mod and Range mod
|
||||
tp: `${fernkampf.system.rangedAttackDamage}`,
|
||||
iniroll: `(${context.inidice})d6 + ${context.inivalue + fernkampf.system.iniModifier ?? 0}`,
|
||||
ini: `${context.inidice}w6 + ${context.inivalue + fernkampf.system.iniModifier ?? 0}`,
|
||||
})
|
||||
})
|
||||
}
|
||||
if (links) {
|
||||
const meitems = []
|
||||
links.system.meleeSkills.forEach((skillInQuestion) => {
|
||||
const item = actorData.items.find(p => p.name === skillInQuestion)
|
||||
if (item) {
|
||||
meitems.push(item)
|
||||
}
|
||||
})
|
||||
meitems.forEach(skill => {
|
||||
const obj = skill
|
||||
context.attacks.push({
|
||||
name: obj.name,
|
||||
using: links.name,
|
||||
atroll: `1d20cs<${object.system.at.links.aktuell + obj.system.at + links.system.attackModifier}`, // TODO consider adding W/M
|
||||
at: `${object.system.at.links.aktuell + obj.system.at + links.system.attackModifier}`,
|
||||
paroll: `1d20cs<${object.system.pa.links.aktuell + obj.system.pa + links.system.parryModifier}`, // TODO consider adding W/M
|
||||
pa: `${object.system.pa.links.aktuell + obj.system.pa + links.system.parryModifier}`,
|
||||
tproll: `${links.system.meleeAttackDamage}`, // TODO consider adding TP/KK mod
|
||||
tp: `${links.system.meleeAttackDamage}`,
|
||||
iniroll: `(${context.inidice})d6 + ${context.inivalue + links.system.iniModifier ?? 0}`,
|
||||
ini: `${context.inidice}w6 + ${context.inivalue + links.system.iniModifier ?? 0}`,
|
||||
})
|
||||
})
|
||||
}
|
||||
if (rechts) {
|
||||
const meitems = []
|
||||
rechts.system.meleeSkills.forEach((skillInQuestion) => {
|
||||
const item = actorData.items.find(p => p.name === skillInQuestion)
|
||||
if (item) {
|
||||
meitems.push(item)
|
||||
}
|
||||
})
|
||||
meitems.forEach(skill => {
|
||||
const obj = skill
|
||||
context.attacks.push({
|
||||
name: obj.name,
|
||||
using: rechts.name,
|
||||
atroll: `1d20cs<${object.system.at.rechts.aktuell + obj.system.at + rechts.system.attackModifier}`, // TODO consider adding W/M
|
||||
at: `${object.system.at.rechts.aktuell + obj.system.at + rechts.system.attackModifier}`,
|
||||
paroll: `1d20cs<${object.system.pa.rechts.aktuell + obj.system.pa + rechts.system.parryModifier}`, // TODO consider adding W/M
|
||||
pa: `${object.system.pa.rechts.aktuell + obj.system.pa + rechts.system.parryModifier}`,
|
||||
tproll: `${rechts.system.meleeAttackDamage}`, // TODO consider adding TP/KK mod
|
||||
tp: `${rechts.system.meleeAttackDamage}`,
|
||||
iniroll: `(${context.inidice})d6 + ${context.inivalue + rechts.system.iniModifier ?? 0}`,
|
||||
ini: `${context.inidice}w6 + ${context.inivalue + rechts.system.iniModifier ?? 0}`,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
return context
|
||||
|
||||
},
|
||||
_onRender: (context, options) => {
|
||||
|
||||
},
|
||||
_getTabConfig: (group) => {
|
||||
group.tabs.push({id: "combat", group: "sheet", label: "Kampf"})
|
||||
},
|
||||
template: `systems/DSA_4-1/templates/actor/character/tab-combat.hbs`
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
export default {
|
||||
_prepareContext: (context, object) => {
|
||||
|
||||
const actorData = context.document
|
||||
context.spells = []
|
||||
context.system = actorData.system
|
||||
context.flags = actorData.flags
|
||||
context.derived = context.document.system
|
||||
context.originalName = actorData.name
|
||||
context.name = context.derived.name ?? actorData.name
|
||||
context.effects = actorData.effects ?? []
|
||||
|
||||
context.isGM = game.user.isGM
|
||||
context.effects = []
|
||||
Object.values(actorData.items).forEach((item, index) => {
|
||||
if (item.type === "ActiveEffect") {
|
||||
const effect = item.effects[0];
|
||||
const conditions = []
|
||||
|
||||
if (effect) {
|
||||
effect.changes.forEach(change => {
|
||||
if (change.key.indexOf("wunden") === -1) {
|
||||
const key = change.key
|
||||
.replace(/system\./g, "")
|
||||
.replace(/\.mod/g, "")
|
||||
.replace(/attribute./g, "")
|
||||
.replace(/.links/g, "(Links)")
|
||||
.replace(/.rechts/g, "(Rechts)")
|
||||
const value = Number(change.value) > 0 ? "+" + change.value : change.value
|
||||
conditions.push(
|
||||
`${key}${value}`
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
context.effects.push({
|
||||
name: item.name,
|
||||
conditions: conditions.join(" "),
|
||||
id: item._id,
|
||||
actor: actorData._id
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
return context
|
||||
},
|
||||
_onRender: (context, options) => {
|
||||
|
||||
},
|
||||
_getTabConfig: (group) => {
|
||||
group.tabs.push({id: "effects", group: "sheet", label: "Effekte"})
|
||||
},
|
||||
template: `systems/DSA_4-1/templates/actor/character/tab-effects.hbs`
|
||||
}
|
||||
|
|
@ -0,0 +1,264 @@
|
|||
import {PlayerCharacterDataModel} from "../../data/character.mjs";
|
||||
|
||||
export default {
|
||||
_prepareContext: (context) => {
|
||||
|
||||
const actorData = context.document
|
||||
context.spells = []
|
||||
context.system = actorData.system
|
||||
context.flags = actorData.flags
|
||||
context.derived = context.document.system
|
||||
context.originalName = actorData.name
|
||||
context.name = context.derived.name ?? actorData.name
|
||||
context.effects = actorData.effects ?? []
|
||||
|
||||
context.equipments = []
|
||||
context.carryingweight = 0
|
||||
actorData.itemTypes.Equipment.forEach((item, index) => {
|
||||
|
||||
// worn items are halved weight
|
||||
|
||||
let effectiveWeight = item.system.weight ?? 0
|
||||
if (context.document.isWorn(item._id)) {
|
||||
effectiveWeight = item.system.weight ? item.system.weight / 2 : 0
|
||||
}
|
||||
|
||||
context.equipments.push({
|
||||
index: index,
|
||||
id: item._id,
|
||||
quantity: item.system.quantity,
|
||||
name: item.name,
|
||||
icon: item.img ?? "",
|
||||
weight: item.system.weight,
|
||||
worn: context.document.isWorn(item._id)
|
||||
})
|
||||
context.carryingweight += item.system.quantity * effectiveWeight;
|
||||
|
||||
})
|
||||
context.maxcarryingcapacity = actorData.system.attribute.kk.aktuell
|
||||
context.carryingpercentage = Math.min((context.carryingweight / context.maxcarryingcapacity) * 100, 100);
|
||||
|
||||
const maxSets = 3
|
||||
const romanNumerals = ["I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X"]
|
||||
context.sets = []
|
||||
for (let setIndex = 0; setIndex < maxSets; setIndex++) {
|
||||
|
||||
context.sets.push({
|
||||
tab: "set" + (setIndex + 1),
|
||||
name: romanNumerals[setIndex],
|
||||
index: setIndex,
|
||||
slots: [
|
||||
{
|
||||
target: "links",
|
||||
id: actorData.system.heldenausruestung[setIndex]?.links,
|
||||
name: actorData.items.get(actorData.system.heldenausruestung[setIndex]?.links)?.name,
|
||||
icon: actorData.items.get(actorData.system.heldenausruestung[setIndex]?.links)?.img
|
||||
},
|
||||
{
|
||||
target: "rechts",
|
||||
id: actorData.system.heldenausruestung[setIndex]?.rechts,
|
||||
name: actorData.items.get(actorData.system.heldenausruestung[setIndex]?.rechts)?.name,
|
||||
icon: actorData.items.get(actorData.system.heldenausruestung[setIndex]?.rechts)?.img
|
||||
},
|
||||
{
|
||||
target: "brust",
|
||||
id: actorData.system.heldenausruestung[setIndex]?.brust,
|
||||
name: actorData.items.get(actorData.system.heldenausruestung[setIndex]?.brust)?.name,
|
||||
icon: actorData.items.get(actorData.system.heldenausruestung[setIndex]?.brust)?.img
|
||||
},
|
||||
{
|
||||
target: "ruecken",
|
||||
id: actorData.system.heldenausruestung[setIndex]?.ruecken,
|
||||
name: actorData.items.get(actorData.system.heldenausruestung[setIndex]?.ruecken)?.name,
|
||||
icon: actorData.items.get(actorData.system.heldenausruestung[setIndex]?.ruecken)?.img
|
||||
},
|
||||
{
|
||||
target: "kopf",
|
||||
id: actorData.system.heldenausruestung[setIndex]?.kopf,
|
||||
name: actorData.items.get(actorData.system.heldenausruestung[setIndex]?.kopf)?.name,
|
||||
icon: actorData.items.get(actorData.system.heldenausruestung[setIndex]?.kopf)?.img
|
||||
},
|
||||
{
|
||||
target: "fernkampf",
|
||||
id: actorData.system.heldenausruestung[setIndex]?.fernkampf,
|
||||
name: actorData.items.get(actorData.system.heldenausruestung[setIndex]?.fernkampf)?.name,
|
||||
icon: actorData.items.get(actorData.system.heldenausruestung[setIndex]?.fernkampf)?.img
|
||||
},
|
||||
{
|
||||
target: "munition",
|
||||
id: actorData.system.heldenausruestung[setIndex]?.munition,
|
||||
name: actorData.items.get(actorData.system.heldenausruestung[setIndex]?.munition)?.name,
|
||||
icon: actorData.items.get(actorData.system.heldenausruestung[setIndex]?.munition)?.img
|
||||
},
|
||||
{
|
||||
target: "armlinks",
|
||||
id: actorData.system.heldenausruestung[setIndex]?.armlinks,
|
||||
name: actorData.items.get(actorData.system.heldenausruestung[setIndex]?.armlinks)?.name,
|
||||
icon: actorData.items.get(actorData.system.heldenausruestung[setIndex]?.armlinks)?.img
|
||||
},
|
||||
{
|
||||
target: "armrechts",
|
||||
id: actorData.system.heldenausruestung[setIndex]?.armrechts,
|
||||
name: actorData.items.get(actorData.system.heldenausruestung[setIndex]?.armrechts)?.name,
|
||||
icon: actorData.items.get(actorData.system.heldenausruestung[setIndex]?.armrechts)?.img
|
||||
},
|
||||
{
|
||||
target: "bauch",
|
||||
id: actorData.system.heldenausruestung[setIndex]?.bauch,
|
||||
name: actorData.items.get(actorData.system.heldenausruestung[setIndex]?.bauch)?.name,
|
||||
icon: actorData.items.get(actorData.system.heldenausruestung[setIndex]?.bauch)?.img
|
||||
},
|
||||
{
|
||||
target: "beinlinks",
|
||||
id: actorData.system.heldenausruestung[setIndex]?.beinlinks,
|
||||
name: actorData.items.get(actorData.system.heldenausruestung[setIndex]?.beinlinks)?.name,
|
||||
icon: actorData.items.get(actorData.system.heldenausruestung[setIndex]?.beinlinks)?.img
|
||||
},
|
||||
{
|
||||
target: "beinrechts",
|
||||
id: actorData.system.heldenausruestung[setIndex]?.beinrechts,
|
||||
name: actorData.items.get(actorData.system.heldenausruestung[setIndex]?.beinrechts)?.name,
|
||||
icon: actorData.items.get(actorData.system.heldenausruestung[setIndex]?.beinrechts)?.img
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
return context
|
||||
},
|
||||
_onRender: (context, options, thisObject) => {
|
||||
|
||||
new foundry.applications.ux.DragDrop.implementation({
|
||||
dragSelector: ".inventory-table .equipment",
|
||||
dropSelector: ".inventory-table",
|
||||
permissions: {
|
||||
dragstart: thisObject._canDragStart.bind(thisObject),
|
||||
drop: thisObject._canDragDrop.bind(thisObject)
|
||||
},
|
||||
callbacks: {
|
||||
dragstart: thisObject._onDragStart.bind(thisObject),
|
||||
drop: thisObject._onDrop.bind(thisObject),
|
||||
dragover: thisObject._onDragOver.bind(thisObject)
|
||||
}
|
||||
}).bind(thisObject.element);
|
||||
|
||||
new ContextMenu(
|
||||
thisObject.element,
|
||||
".equipment",
|
||||
[
|
||||
{
|
||||
name: "Abrüsten",
|
||||
icon: '<i class="fa-solid fa-suitcase"></i>',
|
||||
callback: (target) => {
|
||||
const {itemId} = target.dataset
|
||||
const itemSlot = thisObject.document.isWorn(itemId)
|
||||
const updateObject = thisObject.document.getEquipmentSetUpdateObject()
|
||||
delete updateObject[`system.heldenausruestung.${thisObject.document.system.setEquipped}.${itemSlot}`]
|
||||
thisObject.document.update(updateObject)
|
||||
},
|
||||
condition: (target) => {
|
||||
const {itemId} = target.dataset
|
||||
const itemIsWorn = thisObject.document.isWorn(itemId)
|
||||
return itemIsWorn
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Ausrüsten (Munition)",
|
||||
|
||||
callback: (target) => {
|
||||
const updateObject = thisObject.document.getEquipmentSetUpdateObject()
|
||||
updateObject[`system.heldenausruestung.${thisObject.document.system.setEquipped}.munition`] = target.dataset.itemId
|
||||
thisObject.document.update(updateObject)
|
||||
},
|
||||
condition: (target) => {
|
||||
const {itemId} = target.dataset
|
||||
const item = thisObject.document.items.get(itemId)
|
||||
console.log(item.system.category)
|
||||
return !thisObject.document.isWorn(itemId) && item.system.category.indexOf("Munition") != -1
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Ausrüsten",
|
||||
callback: (target) => {
|
||||
const updateObject = thisObject.document.getEquipmentSetUpdateObject()
|
||||
// find next unoccupied slot and enter the item
|
||||
console.log(updateObject)
|
||||
const nextUnoccupiedSlot = Object.entries(updateObject).find(([key, value]) => {
|
||||
// but not when it is a weapon slot
|
||||
console.log(key, value === null
|
||||
&& key.indexOf(".links") === -1
|
||||
&& key.indexOf(".rechts") === -1
|
||||
&& key.indexOf(".fernkampf") === -1
|
||||
&& key.indexOf(".munition") === -1)
|
||||
return value === null
|
||||
&& key.indexOf(".links") === -1
|
||||
&& key.indexOf(".rechts") === -1
|
||||
&& key.indexOf(".fernkampf") === -1
|
||||
&& key.indexOf(".munition") === -1
|
||||
})
|
||||
updateObject[nextUnoccupiedSlot[0]] = target.dataset.itemId
|
||||
thisObject.document.update(updateObject)
|
||||
},
|
||||
condition: (target) => {
|
||||
const {itemId} = target.dataset
|
||||
const item = thisObject.document.items.get(itemId)
|
||||
return !thisObject.document.isWorn(itemId) && item.system.category.indexOf("Rüstung") != -1
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Ausrüsten (Rechte Hand)",
|
||||
callback: (target) => {
|
||||
const updateObject = thisObject.document.getEquipmentSetUpdateObject()
|
||||
updateObject[`system.heldenausruestung.${thisObject.document.system.setEquipped}.rechts`] = target.dataset.itemId
|
||||
thisObject.document.update(updateObject)
|
||||
},
|
||||
condition: (target) => {
|
||||
const {itemId} = target.dataset
|
||||
const item = thisObject.document.items.get(itemId)
|
||||
return !thisObject.document.isWorn(itemId) && item.system.category.indexOf("Nahkampfwaffe") != -1
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Ausrüsten (Linke Hand)",
|
||||
callback: (target) => {
|
||||
const updateObject = thisObject.document.getEquipmentSetUpdateObject()
|
||||
updateObject[`system.heldenausruestung.${thisObject.document.system.setEquipped}.links`] = target.dataset.itemId
|
||||
thisObject.document.update(updateObject)
|
||||
},
|
||||
condition: (target) => {
|
||||
const {itemId} = target.dataset
|
||||
const item = thisObject.document.items.get(itemId)
|
||||
return !thisObject.document.isWorn(itemId) && item.system.category.indexOf("Nahkampfwaffe") != -1
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Ausrüsten (Fernkampf)",
|
||||
callback: (target) => {
|
||||
const updateObject = thisObject.document.getEquipmentSetUpdateObject()
|
||||
updateObject[`system.heldenausruestung.${thisObject.document.system.setEquipped}.fernkampf`] = target.dataset.itemId
|
||||
thisObject.document.update(updateObject)
|
||||
},
|
||||
condition: (target) => {
|
||||
const {itemId} = target.dataset
|
||||
const item = thisObject.document.items.get(itemId)
|
||||
return !thisObject.document.isWorn(itemId) && item.system.category.indexOf("Fernkampfwaffe") != -1
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Aus dem Inventar entfernen",
|
||||
icon: '<i class="fa-solid fa-trash"></i>',
|
||||
callback: (target) => {
|
||||
thisObject.document.deleteEmbeddedDocuments('Item', [target.dataset.itemId])
|
||||
},
|
||||
condition: (target) => {
|
||||
const {itemId} = target.dataset
|
||||
return !thisObject.document.isWorn(itemId)
|
||||
}
|
||||
}
|
||||
], {jQuery: false});
|
||||
},
|
||||
_getTabConfig: (group) => {
|
||||
group.tabs.push({id: "equipment", group: "sheet", label: "Ausrüstung"})
|
||||
},
|
||||
template: `systems/DSA_4-1/templates/actor/character/tab-equipment.hbs`
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
import {LiturgyData} from "../../data/miracle/liturgydata.mjs";
|
||||
|
||||
export default {
|
||||
_prepareContext: (context) => {
|
||||
|
||||
const actorData = context.document
|
||||
context.system = actorData.system
|
||||
context.flags = actorData.flags
|
||||
context.derived = context.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) {
|
||||
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,
|
||||
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) => {
|
||||
|
||||
},
|
||||
_getTabConfig: (group, thisObject) => {
|
||||
const hasLiturgies = thisObject.document.items.filter(p => p.type === "Liturgy").length > 0 ?? false
|
||||
if (hasLiturgies) {
|
||||
group.tabs.push({id: "liturgies", group: "sheet", label: "Liturgien"})
|
||||
}
|
||||
},
|
||||
template: `systems/DSA_4-1/templates/actor/character/tab-liturgies.hbs`
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
export default {
|
||||
_prepareContext: (context, object) => {
|
||||
const actorData = context.document
|
||||
context.system = actorData.system
|
||||
context.flags = actorData.flags
|
||||
context.derived = context.document.system
|
||||
context.originalName = actorData.name
|
||||
context.name = context.derived.name ?? actorData.name
|
||||
context.effects = actorData.effects ?? []
|
||||
|
||||
return context
|
||||
},
|
||||
_onRender: (context, options) => {
|
||||
|
||||
},
|
||||
_getTabConfig: (group) => {
|
||||
group.tabs.push({id: "meta", group: "sheet", label: "Meta"})
|
||||
},
|
||||
template: `systems/DSA_4-1/templates/actor/character/tab-meta.hbs`
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
export default {
|
||||
_prepareContext: (context) => {
|
||||
|
||||
const actorData = context.document
|
||||
context.spells = []
|
||||
context.system = actorData.system
|
||||
context.flags = actorData.flags
|
||||
context.derived = context.document.system
|
||||
context.originalName = actorData.name
|
||||
context.name = context.derived.name ?? actorData.name
|
||||
context.effects = actorData.effects ?? []
|
||||
|
||||
const prepareEigenschaftRoll = (actorData, name) => {
|
||||
if (name && name !== "*") {
|
||||
return actorData.system.attribute[name.toLowerCase()].aktuell
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
context.skills = {};
|
||||
context.flatSkills = [];
|
||||
|
||||
actorData.itemTypes.Skill.forEach((item, index) => {
|
||||
|
||||
const talentGruppe = item.system.gruppe;
|
||||
const eigenschaften = Object.values(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])}
|
||||
]
|
||||
if (context.skills[talentGruppe] == null) {
|
||||
context.skills[talentGruppe] = [];
|
||||
}
|
||||
const obj = {
|
||||
type: "talent",
|
||||
gruppe: talentGruppe,
|
||||
name: item.name.replace(/Sprachen kennen/g, "Sprache:").replace(/Lesen\/Schreiben/g, "Schrift: "),
|
||||
taw: "" + item.system.taw,
|
||||
tawPath: `system.items.${index}.taw`,
|
||||
werte,
|
||||
rollEigenschaft1: werte[0].value,
|
||||
rollEigenschaft2: werte[1].value,
|
||||
rollEigenschaft3: werte[2].value,
|
||||
eigenschaft1: werte[0].name,
|
||||
eigenschaft2: werte[1].name,
|
||||
eigenschaft3: werte[2].name,
|
||||
probe: `(${eigenschaften.join("/")})`,
|
||||
id: item._id,
|
||||
at: item.system.at,
|
||||
pa: item.system.pa,
|
||||
komplexität: item.system.komplexität
|
||||
};
|
||||
|
||||
if (talentGruppe === "Kampf") {
|
||||
|
||||
if (item.system.pa != null) { // has no parry value so it must be ranged talent (TODO: but it isnt as there can be combatstatistics which has no pa value assigned to)
|
||||
obj.at = item.system.at + context.derived.at.aktuell
|
||||
obj.pa = item.system.pa + context.derived.pa.aktuell
|
||||
} else {
|
||||
obj.at = item.system.at + context.derived.fk.aktuell
|
||||
}
|
||||
}
|
||||
|
||||
context.skills[talentGruppe].push(obj);
|
||||
context.flatSkills.push(obj);
|
||||
}
|
||||
|
||||
)
|
||||
|
||||
return context
|
||||
},
|
||||
_onRender: (context, options) => {
|
||||
|
||||
},
|
||||
_getTabConfig: (group) => {
|
||||
group.tabs.push({id: "skills", group: "sheet", label: "Talente"})
|
||||
},
|
||||
template: `systems/DSA_4-1/templates/actor/character/tab-skills.hbs`
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
export default {
|
||||
_prepareContext: (context, object) => {
|
||||
const actorData = context.document
|
||||
context.system = actorData.system
|
||||
context.flags = actorData.flags
|
||||
context.derived = context.document.system
|
||||
context.originalName = actorData.name
|
||||
context.name = context.derived.name ?? actorData.name
|
||||
context.effects = actorData.effects ?? []
|
||||
|
||||
return context
|
||||
},
|
||||
_onRender: (context, options) => {
|
||||
|
||||
},
|
||||
_getTabConfig: (group) => {
|
||||
group.tabs.push({id: "social", group: "sheet", label: "Soziales"})
|
||||
},
|
||||
template: `systems/DSA_4-1/templates/actor/character/tab-social.hbs`
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
export default {
|
||||
_prepareContext: (context) => {
|
||||
|
||||
const actorData = context.document
|
||||
context.spells = []
|
||||
context.system = actorData.system
|
||||
context.flags = actorData.flags
|
||||
context.derived = context.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())
|
||||
}
|
||||
|
||||
|
||||
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: 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,
|
||||
})
|
||||
}
|
||||
})
|
||||
context.hasSpells = context.spells.length > 0
|
||||
|
||||
return context
|
||||
},
|
||||
_onRender: (context, options) => {
|
||||
|
||||
},
|
||||
_getTabConfig: (group, thisObject) => {
|
||||
const hasSpells = thisObject.document.items.filter(p => p.type === "Spell").length > 0 ?? false
|
||||
if (hasSpells) {
|
||||
group.tabs.push({id: "spells", group: "sheet", label: "Zauber"})
|
||||
}
|
||||
},
|
||||
template: `systems/DSA_4-1/templates/actor/character/tab-spells.hbs`
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,32 +1,114 @@
|
|||
export class CreatureSheet extends foundry.appv1.sheets.ActorSheet {
|
||||
/**@override */
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ['dsa41', 'sheet', 'actor', 'creature'],
|
||||
width: 520,
|
||||
height: 480,
|
||||
const {HandlebarsApplicationMixin} = foundry.applications.api
|
||||
const {ActorSheetV2} = foundry.applications.sheets
|
||||
|
||||
export class CreatureSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
||||
|
||||
/** @inheritDoc */
|
||||
static DEFAULT_OPTIONS = {
|
||||
position: {width: 520, height: 480},
|
||||
classes: ['dsa41', 'sheet', 'actor', 'creature'],
|
||||
tag: 'form',
|
||||
form: {
|
||||
submitOnChange: true,
|
||||
closeOnSubmit: false,
|
||||
handler: CreatureSheet.#onSubmitForm
|
||||
},
|
||||
actions: {
|
||||
removeAttack: CreatureSheet.#removeAttack,
|
||||
addAttack: CreatureSheet.#addAttack,
|
||||
roll: CreatureSheet.#dieRoll,
|
||||
editImage: ActorSheetV2.DEFAULT_OPTIONS.actions.editImage,
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static TABS = {
|
||||
sheet: {
|
||||
tabs: [
|
||||
{
|
||||
navSelector: '.sheet-tabs',
|
||||
contentSelector: '.sheet-body',
|
||||
initial: 'meta',
|
||||
},
|
||||
{id: 'meta', group: 'sheet', label: 'Meta'},
|
||||
{id: 'attacks', group: 'sheet', label: 'Attacken'},
|
||||
{id: 'description', group: 'sheet', label: 'Beschreibung'},
|
||||
],
|
||||
initial: 'meta'
|
||||
}
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
static PARTS = {
|
||||
form: {
|
||||
template: `systems/DSA_4-1/templates/actor/creature/main-sheet.hbs`
|
||||
},
|
||||
meta: {
|
||||
template: `systems/DSA_4-1/templates/actor/creature/tab-meta.hbs`
|
||||
},
|
||||
attacks: {
|
||||
template: `systems/DSA_4-1/templates/actor/creature/tab-attacks.hbs`
|
||||
},
|
||||
description: {
|
||||
template: `systems/DSA_4-1/templates/actor/creature/tab-description.hbs`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle form submission
|
||||
* @this {AdvantageSheet}
|
||||
* @param {SubmitEvent} event
|
||||
* @param {HTMLFormElement} form
|
||||
* @param {FormDataExtended} formData
|
||||
*/
|
||||
static async #onSubmitForm(event, form, formData) {
|
||||
event.preventDefault()
|
||||
|
||||
await this.document.update(formData.object) // Note: formData.object
|
||||
}
|
||||
|
||||
static async #removeAttack(evt) {
|
||||
const {index} = evt.srcElement.dataset;
|
||||
let sans = Array.from(this.document.system.attacks);
|
||||
sans.splice(index, 1);
|
||||
await this.document.update({'system.attacks': sans})
|
||||
}
|
||||
|
||||
static async #dieRoll(evt) {
|
||||
const {rollType, rollName, roll} = evt.srcElement.dataset;
|
||||
let r = new Roll(roll, this.document.getRollData());
|
||||
const label = `${rollType} (${rollName})`
|
||||
await r.toMessage({
|
||||
speaker: ChatMessage.getSpeaker({actor: this.document}),
|
||||
flavor: label,
|
||||
rollMode: game.settings.get('core', 'rollMode'),
|
||||
});
|
||||
}
|
||||
|
||||
/** @override */
|
||||
get template() {
|
||||
return `systems/DSA_4-1/templates/actor/actor-creature-sheet.hbs`;
|
||||
static async #addAttack() {
|
||||
const name = this.element.querySelector('#attack_name').value
|
||||
const at = this.element.querySelector('#attack_at').value
|
||||
const pa = this.element.querySelector('#attack_pa').value
|
||||
const tp = this.element.querySelector('#attack_tp').value
|
||||
|
||||
const newAttack = {
|
||||
name,
|
||||
at,
|
||||
pa,
|
||||
tp
|
||||
}
|
||||
|
||||
await this.document.update({'system.attacks': [...this.document.system.attacks, newAttack]})
|
||||
|
||||
this.element.querySelector('#attack_name').value = ""
|
||||
this.element.querySelector('#attack_at').value = ""
|
||||
this.element.querySelector('#attack_pa').value = ""
|
||||
this.element.querySelector('#attack_tp').value = ""
|
||||
}
|
||||
|
||||
/** @override */
|
||||
getData() {
|
||||
async _prepareContext(options) {
|
||||
|
||||
const context = super.getData();
|
||||
const actorData = context.data;
|
||||
const context = await super._prepareContext(options);
|
||||
const actorData = context.document;
|
||||
|
||||
context.attacks = [];
|
||||
context.actor = actorData;
|
||||
|
||||
actorData.system.attacks.forEach((attack, index) => {
|
||||
context.attacks.push({
|
||||
|
|
@ -43,55 +125,7 @@ export class CreatureSheet extends foundry.appv1.sheets.ActorSheet {
|
|||
})
|
||||
})
|
||||
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
// Everything below here is only needed if the sheet is editable
|
||||
if (!this.isEditable) return;
|
||||
|
||||
html.on('click', '.remove-attack', async (evt) => {
|
||||
const {index} = evt.target.dataset;
|
||||
let sans = Array.from(this.object.system.attacks);
|
||||
sans.splice(index, 1);
|
||||
await this.object.update({'system.attacks': sans})
|
||||
})
|
||||
|
||||
html.on('click', '.attacks-die.die', async (evt) => {
|
||||
const {rollType, rollName, roll} = evt.currentTarget.dataset;
|
||||
let r = new Roll(roll, this.actor.getRollData());
|
||||
const label = `${rollType} (${rollName})`
|
||||
await r.toMessage({
|
||||
speaker: ChatMessage.getSpeaker({actor: this.object}),
|
||||
flavor: label,
|
||||
rollMode: game.settings.get('core', 'rollMode'),
|
||||
});
|
||||
})
|
||||
|
||||
html.on('click', '.editor .add-attack', async (evt) => {
|
||||
const name = html[0].querySelector('#attack_name').value
|
||||
const at = html[0].querySelector('#attack_at').value
|
||||
const pa = html[0].querySelector('#attack_pa').value
|
||||
const tp = html[0].querySelector('#attack_tp').value
|
||||
|
||||
const newAttack = {
|
||||
name,
|
||||
at,
|
||||
pa,
|
||||
tp
|
||||
}
|
||||
|
||||
await this.object.update({'system.attacks': [...this.object.system.attacks, newAttack]})
|
||||
|
||||
evt.target.parentElement.querySelector('#attack_name').value = ""
|
||||
evt.target.parentElement.querySelector('#attack_at').value = ""
|
||||
evt.target.parentElement.querySelector('#attack_pa').value = ""
|
||||
evt.target.parentElement.querySelector('#attack_tp').value = ""
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,42 +1,139 @@
|
|||
export class AusruestungSheet extends foundry.appv1.sheets.ItemSheet {
|
||||
/**@override */
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ['dsa41', 'sheet', 'item', 'equipment'],
|
||||
width: 520,
|
||||
height: 480,
|
||||
const {DocumentSheetV2, HandlebarsApplicationMixin} = foundry.applications.api
|
||||
|
||||
/**
|
||||
* @typedef ApplicationTab
|
||||
* @property {string} id
|
||||
* @property {string} group
|
||||
* @property {boolean} active
|
||||
* @property {string} cssClass
|
||||
* @property {string} [label]
|
||||
* @property {string} [icon]
|
||||
* @property {string} [tooltip]
|
||||
*/
|
||||
|
||||
export class EquipmentSheet extends HandlebarsApplicationMixin(DocumentSheetV2) {
|
||||
|
||||
/** @inheritDoc */
|
||||
static DEFAULT_OPTIONS = {
|
||||
position: {width: 640, height: 480},
|
||||
classes: ['dsa41', 'sheet', 'item', 'equipment'],
|
||||
tag: 'form',
|
||||
form: {
|
||||
submitOnChange: true,
|
||||
closeOnSubmit: false,
|
||||
handler: EquipmentSheet.#onSubmitForm
|
||||
},
|
||||
window: {
|
||||
resizable: true,
|
||||
},
|
||||
actions: {
|
||||
editImage:
|
||||
DocumentSheetV2.DEFAULT_OPTIONS.actions.editImage
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static TABS = {
|
||||
sheet: {
|
||||
tabs: [
|
||||
{
|
||||
navSelector: '.sheet-tabs',
|
||||
contentSelector: '.sheet-body',
|
||||
initial: 'description',
|
||||
},
|
||||
{id: 'meta', group: 'sheet', label: 'Meta'},
|
||||
// Additional Tabs are added based on the nature of this item
|
||||
|
||||
],
|
||||
});
|
||||
initial: 'meta'
|
||||
}
|
||||
}
|
||||
|
||||
/** @override */
|
||||
get template() {
|
||||
return `systems/DSA_4-1/templates/item/item-equipment-sheet.hbs`;
|
||||
|
||||
/** @inheritDoc */
|
||||
static PARTS = {
|
||||
form: {
|
||||
template: `systems/DSA_4-1/templates/item/equipment/main-sheet.hbs`
|
||||
},
|
||||
meta: {
|
||||
template: `systems/DSA_4-1/templates/item/equipment/tab-meta.hbs`
|
||||
},
|
||||
melee: {
|
||||
template: `systems/DSA_4-1/templates/item/equipment/tab-melee.hbs`
|
||||
},
|
||||
ranged: {
|
||||
template: `systems/DSA_4-1/templates/item/equipment/tab-ranged.hbs`
|
||||
},
|
||||
ammunition: {
|
||||
template: `systems/DSA_4-1/templates/item/equipment/tab-ammunition.hbs`
|
||||
},
|
||||
armor: {
|
||||
template: `systems/DSA_4-1/templates/item/equipment/tab-armor.hbs`
|
||||
},
|
||||
settings: {
|
||||
template: `systems/DSA_4-1/templates/item/equipment/tab-settings.hbs`
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
/** @override */
|
||||
getData() {
|
||||
// Retrieve the data structure from the base sheet. You can inspect or log
|
||||
// the context variable to see the structure, but some key properties for
|
||||
// sheets are the actor object, the data object, whether or not it's
|
||||
// editable, the items array, and the effects array.
|
||||
const context = super.getData();
|
||||
/**
|
||||
* Handle form submission
|
||||
* @this {EquipmentSheet}
|
||||
* @param {SubmitEvent} event
|
||||
* @param {HTMLFormElement} form
|
||||
* @param {FormDataExtended} formData
|
||||
*/
|
||||
static async #onSubmitForm(event, form, formData) {
|
||||
event.preventDefault()
|
||||
|
||||
// Use a safe clone of the actor data for further operations.
|
||||
const equipmentData = context.data;
|
||||
let normalisedFormData = {}
|
||||
|
||||
// Add the actor's data to context.data for easier access, as well as flags.
|
||||
context.system = equipmentData.system;
|
||||
context.flags = equipmentData.flags;
|
||||
Object.entries(formData.object).forEach(([key, value]) => {
|
||||
if (Array.isArray(value)) {
|
||||
normalisedFormData[key] = value[0]
|
||||
} else {
|
||||
normalisedFormData[key] = value
|
||||
}
|
||||
})
|
||||
|
||||
context.quantity = context.system.quantity;
|
||||
context.description = context.system.description;
|
||||
// manage categories into array
|
||||
normalisedFormData['system.category'] = []
|
||||
if (normalisedFormData.isMelee) normalisedFormData['system.category'].push("Nahkampfwaffe")
|
||||
delete normalisedFormData.isMelee
|
||||
if (normalisedFormData.isRanged) normalisedFormData['system.category'].push("Fernkampfwaffe")
|
||||
delete normalisedFormData.isRanged
|
||||
if (normalisedFormData.isAmmunition) normalisedFormData['system.category'].push("Munition")
|
||||
delete normalisedFormData.isAmmunition
|
||||
if (normalisedFormData.isArmor) normalisedFormData['system.category'].push("Rüstung")
|
||||
delete normalisedFormData.isArmor
|
||||
|
||||
await this.document.update(normalisedFormData) // Note: formData.object
|
||||
}
|
||||
|
||||
async _preparePartContext(partId, context) {
|
||||
switch (partId) {
|
||||
case 'meta':
|
||||
this.#prepareMetaContext(context)
|
||||
break;
|
||||
case 'melee':
|
||||
this.#prepareMeleeContext(context)
|
||||
break;
|
||||
case 'ranged':
|
||||
this.#prepareRangedContext(context)
|
||||
break;
|
||||
case 'armor':
|
||||
this.#prepareArmorContext(context)
|
||||
break;
|
||||
case 'settings':
|
||||
this.#prepareSettingsContext(context)
|
||||
break;
|
||||
}
|
||||
context.tab = context.tabs[partId]
|
||||
return context
|
||||
}
|
||||
|
||||
#prepareMetaContext(context) {
|
||||
const equipmentData = context.document.system
|
||||
context.system = equipmentData
|
||||
context.quantity = equipmentData.quantity
|
||||
context.description = equipmentData.description
|
||||
context.name = context.document.name
|
||||
context.img = context.document.img
|
||||
|
||||
context.categoryAndOptions = {
|
||||
options: {
|
||||
|
|
@ -44,25 +141,23 @@ export class AusruestungSheet extends foundry.appv1.sheets.ItemSheet {
|
|||
Nahkampfwaffe: "Nahkampfwaffe",
|
||||
Fernkampfwaffe: "Fernkampfwaffe",
|
||||
Behälter: "Behälter",
|
||||
Rüstung: "Rüstung",
|
||||
},
|
||||
entries: context.system.category,
|
||||
entries: equipmentData.category,
|
||||
targetField: "category"
|
||||
};
|
||||
context.isMeleeWeapon = context.system.category.includes("Nahkampfwaffe");
|
||||
context.isRangedWeapon = context.system.category.includes("Fernkampfwaffe");
|
||||
context.isContainer = context.system.category.includes("Behälter");
|
||||
context.isArmor = context.system.category.includes("Rüstung");
|
||||
context.price = context.system.price;
|
||||
context.weight = context.system.weight;
|
||||
}
|
||||
|
||||
#prepareMeleeContext(context) {
|
||||
const equipmentData = context.document.system
|
||||
context.system = equipmentData
|
||||
context.meleeSkillsAndOptions = {
|
||||
options: {
|
||||
"": "",
|
||||
Dolche: "Dolche",
|
||||
Fechtwaffen: "Fechtwaffen",
|
||||
Säbel: "Säbel",
|
||||
"Säbel": "Säbel",
|
||||
Schwerter: "Schwerter",
|
||||
Anderthalbhänder: "Anderthalbhänder",
|
||||
"Anderthalbhänder": "Anderthalbhänder",
|
||||
"Zweihandschwerter/-säbel": "Zweihandschwerter/-säbel",
|
||||
"Infanteriewaffen": "Infanteriewaffen",
|
||||
"Speere": "Speere",
|
||||
|
|
@ -72,9 +167,13 @@ export class AusruestungSheet extends foundry.appv1.sheets.ItemSheet {
|
|||
"Kettenwaffen": "Kettenwaffen",
|
||||
"Raufen": "Raufen"
|
||||
},
|
||||
entries: context.system.meleeSkills,
|
||||
entries: equipmentData.meleeSkills,
|
||||
targetField: "meleeSkills"
|
||||
}
|
||||
}
|
||||
|
||||
#prepareRangedContext(context) {
|
||||
const equipmentData = context.document.system
|
||||
context.rangedSkillsAndOptions = {
|
||||
options: {
|
||||
"": "",
|
||||
|
|
@ -84,24 +183,117 @@ export class AusruestungSheet extends foundry.appv1.sheets.ItemSheet {
|
|||
"Armbrust": "Armbrust",
|
||||
"Bogen": "Bogen",
|
||||
},
|
||||
entries: context.system.rangedSkills,
|
||||
entries: equipmentData.rangedSkills,
|
||||
targetField: "rangedSkills"
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
#prepareAmmunitionContext(context) {
|
||||
|
||||
html.on('change', '.array-editor select', (evt) => {
|
||||
const addingValue = evt.currentTarget.value;
|
||||
const fieldToTarget = evt.currentTarget.dataset.targetField;
|
||||
const newSkills = [...this.object.system[fieldToTarget], addingValue];
|
||||
}
|
||||
|
||||
this.object.update({system: {[fieldToTarget]: newSkills}});
|
||||
evt.currentTarget.value = "";
|
||||
#prepareArmorContext(context) {
|
||||
|
||||
}
|
||||
|
||||
#prepareSettingsContext(context) {
|
||||
context.isMelee = this.document.system.category.includes("Nahkampfwaffe")
|
||||
context.isRanged = this.document.system.category.includes("Fernkampfwaffe")
|
||||
context.isAmmunition = this.document.system.category.includes("Munition")
|
||||
context.isArmor = this.document.system.category.includes("Rüstung")
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Tabs based on the items nature
|
||||
*
|
||||
* @param {String} group
|
||||
* @private
|
||||
*/
|
||||
_getTabsConfig(group) {
|
||||
|
||||
const tabs = foundry.utils.deepClone(super._getTabsConfig(group))
|
||||
|
||||
const category = this.document.system.category
|
||||
/**
|
||||
*
|
||||
* @type {[{ApplicationTab}]}
|
||||
*/
|
||||
|
||||
if (category.includes("Nahkampfwaffe")) {
|
||||
tabs.tabs.push({
|
||||
id: 'melee', group: group, label: 'Nahkampfwaffe'
|
||||
})
|
||||
}
|
||||
if (category.includes("Fernkampfwaffe")) {
|
||||
tabs.tabs.push({
|
||||
id: 'ranged', group: group, label: 'Fernkampfwaffe'
|
||||
})
|
||||
}
|
||||
if (category.includes("Rüstung")) {
|
||||
tabs.tabs.push({
|
||||
id: 'armor', group: group, label: 'Rüstung'
|
||||
})
|
||||
}
|
||||
|
||||
tabs.tabs.push({
|
||||
id: 'settings', group: group, label: 'Einstellungen'
|
||||
})
|
||||
|
||||
return tabs
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async _prepareContext(options) {
|
||||
|
||||
const context = await super._prepareContext(options)
|
||||
context.price = context.document.system.price
|
||||
context.weight = context.document.system.weight
|
||||
context.inventoryItems = []
|
||||
context.containerVolume = context.document.system.containerVolume
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
/**
|
||||
* Actions performed after any render of the Application.
|
||||
* Post-render steps are not awaited by the render process.
|
||||
* @param {ApplicationRenderContext} context Prepared context data
|
||||
* @param {RenderOptions} options Provided render options
|
||||
* @protected
|
||||
*/
|
||||
_onRender(context, options) {
|
||||
|
||||
new foundry.applications.ux.DragDrop.implementation({
|
||||
dropSelector: ".inventory-table",
|
||||
permissions: {
|
||||
drop: this._canDragDrop.bind(this)
|
||||
},
|
||||
callbacks: {
|
||||
drop: this._onDrop.bind(this)
|
||||
}
|
||||
}).bind(this.element);
|
||||
}
|
||||
|
||||
_canDragDrop(event) {
|
||||
console.log(event)
|
||||
return true
|
||||
}
|
||||
|
||||
async _onDrop(event) {
|
||||
const data = TextEditor.implementation.getDragEventData(event);
|
||||
|
||||
// Dropped Documents
|
||||
const documentClass = foundry.utils.getDocumentClass(data.type);
|
||||
if (documentClass) {
|
||||
|
||||
const document = await documentClass.fromDropData(data)
|
||||
|
||||
console.log(document, document.parent)
|
||||
|
||||
// Dropped Documents
|
||||
|
||||
document.update({"parent": this.document})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,85 +1,143 @@
|
|||
export class GroupSheet extends foundry.appv1.sheets.ActorSheet {
|
||||
/**@override */
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ['dsa41', 'sheet', 'actor', 'group'],
|
||||
width: 520,
|
||||
height: 480,
|
||||
tabs: [
|
||||
{
|
||||
navSelector: '.sheet-tabs',
|
||||
contentSelector: '.sheet-body',
|
||||
initial: 'description',
|
||||
},
|
||||
],
|
||||
});
|
||||
const {HandlebarsApplicationMixin} = foundry.applications.api
|
||||
const {ActorSheetV2} = foundry.applications.sheets
|
||||
const {ContextMenu} = foundry.applications.ux
|
||||
|
||||
export class GroupSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
||||
|
||||
/** @inheritDoc */
|
||||
static DEFAULT_OPTIONS = {
|
||||
position: {width: 520, height: 480},
|
||||
classes: ['dsa41', 'sheet', 'actor', 'group'],
|
||||
tag: 'form',
|
||||
dragDrop: [{
|
||||
dropSelector: '.tab.inventory.active'
|
||||
}],
|
||||
form: {
|
||||
submitOnChange: true,
|
||||
closeOnSubmit: false,
|
||||
handler: GroupSheet.#onSubmitForm
|
||||
},
|
||||
window: {
|
||||
resizable: true,
|
||||
},
|
||||
actions: {
|
||||
roll: GroupSheet.#dieRoll,
|
||||
editImage: ActorSheetV2.DEFAULT_OPTIONS.actions.editImage,
|
||||
openEmbeddedDocument: GroupSheet.#openEmbeddedDocument,
|
||||
openActorDocument: GroupSheet.#openActorDocument,
|
||||
}
|
||||
}
|
||||
|
||||
static async onDroppedData(group, sheet, data) {
|
||||
if (data.type === "Actor") {
|
||||
const uuid = await foundry.utils.parseUuid(data.uuid);
|
||||
const character = await (game.actors.get(uuid.id))
|
||||
|
||||
// check if character already is part of the group
|
||||
if (group.system.characters.includes(character._id)) {
|
||||
ui.notifications.warn(`${character.name} befindet sich bereits in der Heldengruppe ${group.name}`)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// update group
|
||||
let settings = {...group.system.settings}
|
||||
character.items.filter((i) => i.type === "Advantage").forEach((advantage) => {
|
||||
if (!settings[sheet.#stringToKeyFieldName(advantage.name)]) {
|
||||
settings[sheet.#stringToKeyFieldName(advantage.name)] = false
|
||||
}
|
||||
})
|
||||
character.items.filter((i) => i.type === "Skill").forEach((skill) => {
|
||||
if (!settings[sheet.#stringToKeyFieldName(skill.name)]) {
|
||||
settings[sheet.#stringToKeyFieldName(skill.name)] = false
|
||||
}
|
||||
})
|
||||
|
||||
await group.update({
|
||||
system: {
|
||||
characters: [
|
||||
...group.system.characters,
|
||||
character._id
|
||||
],
|
||||
settings: settings
|
||||
}
|
||||
})
|
||||
ui.notifications.info(`${character.name} ist der Heldengruppe ${group.name} beigetreten`)
|
||||
static TABS = {
|
||||
sheet: {
|
||||
tabs: [
|
||||
{id: 'members', group: 'sheet', label: 'Gruppenmitglieder'},
|
||||
{id: 'inventory', group: 'sheet', label: 'Gruppeninventar'},
|
||||
],
|
||||
initial: 'members'
|
||||
}
|
||||
if (data.type === "Equipment") {
|
||||
const uuid = await foundry.utils.parseUuid(data.uuid);
|
||||
const equipment = await (game.actors.get(uuid.id))
|
||||
ui.notifications.info(`${equipment.name} befindet sich nun im Inventar der Heldengruppe ${group.name}`)
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
static PARTS = {
|
||||
form: {
|
||||
template: `systems/DSA_4-1/templates/actor/group/main-sheet.hbs`
|
||||
},
|
||||
members: {
|
||||
template: `systems/DSA_4-1/templates/actor/group/tab-members.hbs`
|
||||
},
|
||||
inventory: {
|
||||
template: `systems/DSA_4-1/templates/actor/group/tab-inventory.hbs`
|
||||
},
|
||||
settings: {
|
||||
template: `systems/DSA_4-1/templates/actor/group/tab-settings.hbs`
|
||||
}
|
||||
}
|
||||
|
||||
constructor(options = {}) {
|
||||
super(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle form submission
|
||||
* @this {AdvantageSheet}
|
||||
* @param {SubmitEvent} event
|
||||
* @param {HTMLFormElement} form
|
||||
* @param {FormDataExtended} formData
|
||||
*/
|
||||
static async #onSubmitForm(event, form, formData) {
|
||||
event.preventDefault()
|
||||
|
||||
if (formData.object.name) {
|
||||
await (game.folders.get(this.document.system.groupId)).update({name: formData.object.name})
|
||||
}
|
||||
|
||||
await this.document.update(formData.object) // Note: formData.object
|
||||
}
|
||||
|
||||
#stringToKeyFieldName(s) {
|
||||
return s
|
||||
}
|
||||
|
||||
/** @override */
|
||||
get template() {
|
||||
return `systems/DSA_4-1/templates/actor/group-sheet.hbs`;
|
||||
|
||||
static #openEmbeddedDocument(event) {
|
||||
const dataset = event.target.parentElement.dataset
|
||||
const id = dataset.itemId ?? dataset.id
|
||||
this.document.items.get(id).sheet.render(true)
|
||||
}
|
||||
|
||||
|
||||
static async #openActorDocument(event) {
|
||||
const dataset = event.target.parentElement.dataset
|
||||
const id = dataset.itemId ?? dataset.id
|
||||
game.actors.get(id).sheet.render(true)
|
||||
}
|
||||
|
||||
static async #dieRoll(evt) {
|
||||
console.log(evt)
|
||||
}
|
||||
|
||||
async #onUpdateCharacterSettings(data) {
|
||||
if (data.type === "character") {
|
||||
|
||||
// update group
|
||||
let settings = {...this.document.system.settings}
|
||||
data.items.filter((i) => i.type === "Advantage").forEach((advantage) => {
|
||||
if (!settings[this.#stringToKeyFieldName(advantage.name)]) {
|
||||
settings[this.#stringToKeyFieldName(advantage.name)] = false
|
||||
}
|
||||
})
|
||||
data.items.filter((i) => i.type === "Skill").forEach((skill) => {
|
||||
if (!settings[this.#stringToKeyFieldName(skill.name)]) {
|
||||
settings[this.#stringToKeyFieldName(skill.name)] = false
|
||||
}
|
||||
})
|
||||
|
||||
await this.document.update({"system.settings": settings})
|
||||
}
|
||||
}
|
||||
|
||||
_getTabsConfig(group) {
|
||||
const tabs = foundry.utils.deepClone(super._getTabsConfig(group))
|
||||
|
||||
// Modify tabs based on document properties
|
||||
if (game.user.isGM) {
|
||||
tabs.tabs.push({id: "settings", group: "sheet", label: "Einstellungen"})
|
||||
}
|
||||
|
||||
return tabs
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async getData() {
|
||||
const context = super.getData();
|
||||
|
||||
// Use a safe clone of the actor data for further operations.
|
||||
const groupData = context.data;
|
||||
|
||||
// Add the actor's data to context.data for easier access, as well as flags.
|
||||
context.system = groupData.system;
|
||||
context.flags = groupData.flags;
|
||||
async _prepareContext(options) {
|
||||
const context = await super._prepareContext(options)
|
||||
const groupData = context.document
|
||||
context.system = groupData.system
|
||||
context.flags = groupData.flags
|
||||
context.characters = []
|
||||
context.isGM = game.user.isGM;
|
||||
context.isGM = game.user.isGM
|
||||
context.name = groupData.name
|
||||
context.img = groupData.img
|
||||
|
||||
context.fields = [];
|
||||
|
||||
|
|
@ -101,8 +159,11 @@ export class GroupSheet extends foundry.appv1.sheets.ActorSheet {
|
|||
}
|
||||
}
|
||||
|
||||
for (const characterId of groupData.system.characters) {
|
||||
const character = await game.actors.get(characterId)
|
||||
// TODO hook on changes in the given folder
|
||||
const characters = await game.folders.get(groupData.system.groupId).contents
|
||||
console.log(characters)
|
||||
|
||||
for (const character of characters) {
|
||||
|
||||
character.items.filter((i) => i.type === "Advantage").filter((i) => hiddenFields.includes(this.#stringToKeyFieldName(i.name))).map((advantage) => {
|
||||
const n = this.#stringToKeyFieldName(advantage.name)
|
||||
|
|
@ -117,15 +178,8 @@ export class GroupSheet extends foundry.appv1.sheets.ActorSheet {
|
|||
if (!context.fields[n]) {
|
||||
context.fields[n] = {}
|
||||
}
|
||||
const eigenschaften = Object.values(skill.system.probe);
|
||||
context.fields[n][character.name] = {
|
||||
taw: skill.system.taw,
|
||||
eigenschaft1: eigenschaften[0],
|
||||
eigenschaft2: eigenschaften[1],
|
||||
eigenschaft3: eigenschaften[2],
|
||||
rollEigenschaft1: character.system.attribute[eigenschaften[0].toLowerCase()].aktuell,
|
||||
rollEigenschaft2: character.system.attribute[eigenschaften[1].toLowerCase()].aktuell,
|
||||
rollEigenschaft3: character.system.attribute[eigenschaften[2].toLowerCase()].aktuell,
|
||||
taw: skill.system.taw ?? "0",
|
||||
name: skill.name,
|
||||
actor: character._id,
|
||||
}
|
||||
|
|
@ -153,11 +207,11 @@ export class GroupSheet extends foundry.appv1.sheets.ActorSheet {
|
|||
}
|
||||
}
|
||||
|
||||
context.equipments = [];
|
||||
const actorData = context.data;
|
||||
Object.values(actorData.items).forEach((item, index) => {
|
||||
context.inventoryItems = [];
|
||||
const actorData = context.document;
|
||||
actorData.items.forEach((item, index) => {
|
||||
if (item.type === "Equipment") {
|
||||
context.equipments.push({
|
||||
context.inventoryItems.push({
|
||||
index: index,
|
||||
id: item._id,
|
||||
quantity: item.system.quantity,
|
||||
|
|
@ -173,110 +227,8 @@ export class GroupSheet extends foundry.appv1.sheets.ActorSheet {
|
|||
return await context;
|
||||
}
|
||||
|
||||
openEmbeddedDocument(documentId) {
|
||||
this.object.items.get(documentId).sheet.render(true)
|
||||
}
|
||||
|
||||
|
||||
_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,
|
||||
}
|
||||
}
|
||||
|
||||
async _onTalentRoll(event) {
|
||||
event.preventDefault();
|
||||
const dataset = event.currentTarget.dataset;
|
||||
const actor = await game.actors.get(dataset.actorId);
|
||||
console.log(dataset, actor)
|
||||
if (dataset.rolleigenschaft1) {
|
||||
let roll1 = new Roll("3d20", 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: actor}),
|
||||
flavor: ` ${dsaDieRollEvaluated.meisterlich ? 'Meisterlich geschafft' : 'Geschafft'} mit ${dsaDieRollEvaluated.tap} Punkten übrig`,
|
||||
}, {rollMode: "gmroll"})
|
||||
} else { // misserfolg
|
||||
evaluated1.toMessage({
|
||||
speaker: ChatMessage.getSpeaker({actor: actor}),
|
||||
flavor: ` ${dsaDieRollEvaluated.meisterlich ? 'Gepatzt' : ''} mit ${Math.abs(dsaDieRollEvaluated.tap)} Punkten daneben`,
|
||||
}, {rollMode: "gmroll"})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
html.on('click', '.owneroption.clickable', async (evt) => {
|
||||
const dataset = evt.target.dataset;
|
||||
const group = this.object;
|
||||
switch (dataset.operation) {
|
||||
case "removeFromParty":
|
||||
const charactersWithoutMember = group.system.characters.filter(id => id !== dataset.id)
|
||||
await group.update({
|
||||
system: {
|
||||
characters: charactersWithoutMember
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
html.on('click', '.header.clickable', async (evt) => {
|
||||
const {id, operation} = evt.currentTarget.dataset;
|
||||
if (operation === "openActorSheet") {
|
||||
evt.stopPropagation();
|
||||
(await game.actors.get(id)).sheet.render(true);
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
html.on('click', '.equipment', (evt) => {
|
||||
this.openEmbeddedDocument(evt.target.dataset.id);
|
||||
evt.stopPropagation();
|
||||
})
|
||||
|
||||
html.on('click', ".rollable", (evt) => {
|
||||
this._onTalentRoll(evt)
|
||||
evt.stopPropagation()
|
||||
})
|
||||
|
||||
new ContextMenu(html, '.equipment', [
|
||||
_onRender(context, options) {
|
||||
/*ContextMenu.implementation.create(this, this.element, ".equipment", [
|
||||
{
|
||||
name: "Aus dem Gruppeninventar entfernen",
|
||||
icon: '<i class="fa-solid fa-trash"></i>',
|
||||
|
|
@ -285,6 +237,84 @@ export class GroupSheet extends foundry.appv1.sheets.ActorSheet {
|
|||
},
|
||||
condition: () => true
|
||||
}
|
||||
]);
|
||||
], {
|
||||
jQuery: false
|
||||
});*/
|
||||
|
||||
// Drag-drop
|
||||
new foundry.applications.ux.DragDrop.implementation({
|
||||
dragSelector: ".inventory-table .equipment",
|
||||
dropSelector: ".inventory-table",
|
||||
permissions: {
|
||||
dragstart: this._canDragStart.bind(this),
|
||||
drop: this._canDragDrop.bind(this)
|
||||
},
|
||||
callbacks: {
|
||||
dragstart: this._onDragStart.bind(this),
|
||||
drop: this._onDrop.bind(this)
|
||||
}
|
||||
}).bind(this.element);
|
||||
|
||||
// Update Group Members when either an Actor was moved into the linked Folder or removed from the linked Folder
|
||||
Hooks.on('updateActor', (data) => {
|
||||
if (data._id !== this.document._id) { // dont update yourself when you update yourself... baka!
|
||||
if (data.type === "character" && data.folder?._id === this.document.system.groupId) {
|
||||
this.#onUpdateCharacterSettings(data)
|
||||
this.render()
|
||||
} else if (data.type === "character") {
|
||||
this.render()
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* An event that occurs when a drag workflow begins for a draggable item on the sheet.
|
||||
* @param {DragEvent} event The initiating drag start event
|
||||
* @returns {Promise<void>}
|
||||
* @protected
|
||||
*/
|
||||
async _onDragStart(event) {
|
||||
const target = event.currentTarget;
|
||||
if ("link" in event.target.dataset) return;
|
||||
let dragData;
|
||||
|
||||
// Owned Items
|
||||
if (target.dataset.itemId) {
|
||||
const item = this.actor.items.get(target.dataset.itemId);
|
||||
dragData = item.toDragData();
|
||||
}
|
||||
|
||||
// Active Effect
|
||||
if (target.dataset.effectId) {
|
||||
const effect = this.actor.effects.get(target.dataset.effectId);
|
||||
dragData = effect.toDragData();
|
||||
}
|
||||
|
||||
// Set data transfer
|
||||
if (!dragData) return;
|
||||
event.dataTransfer.setData("text/plain", JSON.stringify(dragData));
|
||||
}
|
||||
|
||||
// TODO needs to be fixed once Character Sheet is migrated to ActorSheetV2
|
||||
async _onDrop(event) {
|
||||
const data = TextEditor.implementation.getDragEventData(event);
|
||||
const actor = this.actor;
|
||||
const allowed = Hooks.call("dropActorSheetData", actor, this, data);
|
||||
if (allowed === false) return;
|
||||
|
||||
// Dropped Documents
|
||||
const documentClass = foundry.utils.getDocumentClass(data.type);
|
||||
if (documentClass) {
|
||||
const document = await documentClass.fromDropData(data);
|
||||
await this._onDropDocument(event, document);
|
||||
|
||||
// No duplication by moving items from one actor to another
|
||||
if (document.parent) {
|
||||
document.parent.items.get(document._id).delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,50 +1,62 @@
|
|||
export class LiturgySheet extends foundry.appv1.sheets.ItemSheet {
|
||||
/**@override */
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ['dsa41', 'sheet', 'item', 'liturgy'],
|
||||
width: 520,
|
||||
height: 480,
|
||||
const {DocumentSheetV2, HandlebarsApplicationMixin} = foundry.applications.api
|
||||
|
||||
export class LiturgySheet extends HandlebarsApplicationMixin(DocumentSheetV2) {
|
||||
|
||||
/** @inheritDoc */
|
||||
static DEFAULT_OPTIONS = {
|
||||
position: {width: 520, height: 480},
|
||||
classes: ['dsa41', 'sheet', 'item', 'liturgy'],
|
||||
tag: 'form',
|
||||
form: {
|
||||
submitOnChange: true,
|
||||
closeOnSubmit: false,
|
||||
handler: LiturgySheet.#onSubmitForm
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
static TABS = {
|
||||
sheet: {
|
||||
tabs: [
|
||||
{
|
||||
navSelector: '.sheet-tabs',
|
||||
contentSelector: '.sheet-body',
|
||||
initial: 'description',
|
||||
},
|
||||
{id: 'json', group: 'sheet', label: 'JSON'},
|
||||
],
|
||||
});
|
||||
initial: 'json'
|
||||
}
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
static PARTS = {
|
||||
form: {
|
||||
template: `systems/DSA_4-1/templates/item/liturgy/main-sheet.hbs`
|
||||
},
|
||||
json: {
|
||||
template: `systems/DSA_4-1/templates/item/liturgy/tab-json.hbs`
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle form submission
|
||||
* @this {EquipmentSheet}
|
||||
* @param {SubmitEvent} event
|
||||
* @param {HTMLFormElement} form
|
||||
* @param {FormDataExtended} formData
|
||||
*/
|
||||
static async #onSubmitForm(event, form, formData) {
|
||||
event.preventDefault()
|
||||
|
||||
await this.document.update(formData.object) // Note: formData.object
|
||||
}
|
||||
|
||||
/** @override */
|
||||
get template() {
|
||||
return `systems/DSA_4-1/templates/item/item-liturgy-sheet.hbs`;
|
||||
}
|
||||
async _prepareContext(options) {
|
||||
const context = await super._prepareContext(options);
|
||||
|
||||
/** @override */
|
||||
getData() {
|
||||
// Retrieve the data structure from the base sheet. You can inspect or log
|
||||
// the context variable to see the structure, but some key properties for
|
||||
// sheets are the actor object, the data object, whether or not it's
|
||||
// editable, the items array, and the effects array.
|
||||
const context = super.getData();
|
||||
const liturgyData = context.document;
|
||||
|
||||
// Use a safe clone of the actor data for further operations.
|
||||
const liturgyData = context.data;
|
||||
|
||||
// Add the actor's data to context.data for easier access, as well as flags.
|
||||
context.system = liturgyData.system;
|
||||
context.flags = liturgyData.flags;
|
||||
context.json = JSON.stringify(liturgyData);
|
||||
return context;
|
||||
}
|
||||
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
// Everything below here is only needed if the sheet is editable
|
||||
if (this.isEditable) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,37 +1,61 @@
|
|||
export class SkillSheet extends foundry.appv1.sheets.ItemSheet {
|
||||
/**@override */
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ['dsa41', 'sheet', 'item', 'skill'],
|
||||
width: 520,
|
||||
height: 480,
|
||||
const {DocumentSheetV2, HandlebarsApplicationMixin} = foundry.applications.api
|
||||
|
||||
export class SkillSheet extends HandlebarsApplicationMixin(DocumentSheetV2) {
|
||||
|
||||
/** @inheritDoc */
|
||||
static DEFAULT_OPTIONS = {
|
||||
position: {width: 520, height: 480},
|
||||
classes: ['dsa41', 'sheet', 'item', 'skill'],
|
||||
tag: 'form',
|
||||
form: {
|
||||
submitOnChange: true,
|
||||
closeOnSubmit: false,
|
||||
handler: SkillSheet.#onSubmitForm
|
||||
}
|
||||
}
|
||||
|
||||
static TABS = {
|
||||
sheet: {
|
||||
tabs: [
|
||||
{
|
||||
navSelector: '.sheet-tabs',
|
||||
contentSelector: '.sheet-body',
|
||||
initial: 'meta',
|
||||
},
|
||||
{id: 'meta', group: 'sheet', label: 'Meta'},
|
||||
{id: 'description', group: 'sheet', label: 'Beschreibung'},
|
||||
],
|
||||
});
|
||||
initial: 'meta'
|
||||
}
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
static PARTS = {
|
||||
form: {
|
||||
template: `systems/DSA_4-1/templates/item/skill/main-sheet.hbs`
|
||||
},
|
||||
meta: {
|
||||
template: `systems/DSA_4-1/templates/item/skill/tab-meta.hbs`
|
||||
},
|
||||
description: {
|
||||
template: `systems/DSA_4-1/templates/item/skill/tab-description.hbs`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle form submission
|
||||
* @this {SkillSheet}
|
||||
* @param {SubmitEvent} event
|
||||
* @param {HTMLFormElement} form
|
||||
* @param {FormDataExtended} formData
|
||||
*/
|
||||
static async #onSubmitForm(event, form, formData) {
|
||||
event.preventDefault()
|
||||
|
||||
await this.document.update(formData.object) // Note: formData.object
|
||||
}
|
||||
|
||||
/** @override */
|
||||
get template() {
|
||||
return `systems/DSA_4-1/templates/item/item-skill-sheet.hbs`;
|
||||
}
|
||||
async _prepareContext(options) {
|
||||
|
||||
/** @override */
|
||||
getData() {
|
||||
// Retrieve the data structure from the base sheet. You can inspect or log
|
||||
// the context variable to see the structure, but some key properties for
|
||||
// sheets are the actor object, the data object, whether or not it's
|
||||
// editable, the items array, and the effects array.
|
||||
const context = super.getData();
|
||||
const context = await super._prepareContext(options)
|
||||
const skillData = context.document;
|
||||
|
||||
// Use a safe clone of the actor data for further operations.
|
||||
const skillData = context.data;
|
||||
|
||||
// Add the actor's data to context.data for easier access, as well as flags.
|
||||
context.system = skillData.system;
|
||||
context.flags = skillData.flags;
|
||||
context.categoryOptions = {
|
||||
|
|
@ -45,21 +69,11 @@ export class SkillSheet extends foundry.appv1.sheets.ItemSheet {
|
|||
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
|
||||
context.isCombat = skillData.system.gruppe === "Kampf"
|
||||
context.isTalent = skillData.system.gruppe !== "Kampf"
|
||||
context.isLanguage = skillData.system.gruppe === "Sprachen" || skillData.system.gruppe === "Schriften"
|
||||
context.hasRequirement = skillData.system.voraussetzung?.talent != null ?? false
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
// Everything below here is only needed if the sheet is editable
|
||||
if (!this.isEditable) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,51 +1,62 @@
|
|||
export class SpecialAbilitySheet extends foundry.appv1.sheets.ItemSheet {
|
||||
/**@override */
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ['dsa41', 'sheet', 'item', 'specialability'],
|
||||
width: 520,
|
||||
height: 480,
|
||||
const {DocumentSheetV2, HandlebarsApplicationMixin} = foundry.applications.api
|
||||
|
||||
export class SpecialAbilitySheet extends HandlebarsApplicationMixin(DocumentSheetV2) {
|
||||
|
||||
/** @inheritDoc */
|
||||
static DEFAULT_OPTIONS = {
|
||||
position: {width: 520, height: 480},
|
||||
classes: ['dsa41', 'sheet', 'item', 'specialability'],
|
||||
tag: 'form',
|
||||
form: {
|
||||
submitOnChange: true,
|
||||
closeOnSubmit: false,
|
||||
handler: SpecialAbilitySheet.#onSubmitForm
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
static TABS = {
|
||||
sheet: {
|
||||
tabs: [
|
||||
{
|
||||
navSelector: '.sheet-tabs',
|
||||
contentSelector: '.sheet-body',
|
||||
initial: 'description',
|
||||
},
|
||||
{id: 'json', group: 'sheet', label: 'JSON'},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
/** @override */
|
||||
get template() {
|
||||
return `systems/DSA_4-1/templates/item/item-special-ability-sheet.hbs`;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
getData() {
|
||||
// Retrieve the data structure from the base sheet. You can inspect or log
|
||||
// the context variable to see the structure, but some key properties for
|
||||
// sheets are the actor object, the data object, whether or not it's
|
||||
// editable, the items array, and the effects array.
|
||||
const context = super.getData();
|
||||
|
||||
// Use a safe clone of the actor data for further operations.
|
||||
const advantageData = context.data;
|
||||
|
||||
// Add the actor's data to context.data for easier access, as well as flags.
|
||||
context.system = advantageData.system;
|
||||
context.flags = advantageData.flags;
|
||||
context.json = JSON.stringify(advantageData.system, null, 4);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
// Everything below here is only needed if the sheet is editable
|
||||
if (!this.isEditable) {
|
||||
|
||||
initial: 'json'
|
||||
}
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
static PARTS = {
|
||||
form: {
|
||||
template: `systems/DSA_4-1/templates/item/specialability/main-sheet.hbs`
|
||||
},
|
||||
json: {
|
||||
template: `systems/DSA_4-1/templates/item/specialability/tab-json.hbs`
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle form submission
|
||||
* @this {EquipmentSheet}
|
||||
* @param {SubmitEvent} event
|
||||
* @param {HTMLFormElement} form
|
||||
* @param {FormDataExtended} formData
|
||||
*/
|
||||
static async #onSubmitForm(event, form, formData) {
|
||||
event.preventDefault()
|
||||
|
||||
await this.document.update(formData.object) // Note: formData.object
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async _prepareContext(options) {
|
||||
const context = await super._prepareContext(options);
|
||||
|
||||
const specialabilityData = context.document;
|
||||
|
||||
context.system = specialabilityData.system;
|
||||
context.flags = specialabilityData.flags;
|
||||
context.json = JSON.stringify(specialabilityData);
|
||||
return context;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,49 +1,69 @@
|
|||
export class SpellSheet extends foundry.appv1.sheets.ItemSheet {
|
||||
/**@override */
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ['dsa41', 'sheet', 'item', 'spell'],
|
||||
width: 520,
|
||||
height: 480,
|
||||
const {DocumentSheetV2, HandlebarsApplicationMixin} = foundry.applications.api
|
||||
|
||||
export class SpellSheet extends HandlebarsApplicationMixin(DocumentSheetV2) {
|
||||
|
||||
|
||||
/** @inheritDoc */
|
||||
static DEFAULT_OPTIONS = {
|
||||
position: {width: 520, height: 480},
|
||||
classes: ['dsa41', 'sheet', 'item', 'spell'],
|
||||
tag: 'form',
|
||||
form: {
|
||||
submitOnChange: true,
|
||||
closeOnSubmit: false,
|
||||
handler: SpellSheet.#onSubmitForm
|
||||
}
|
||||
}
|
||||
|
||||
static TABS = {
|
||||
sheet: {
|
||||
tabs: [
|
||||
{
|
||||
navSelector: '.sheet-tabs',
|
||||
contentSelector: '.sheet-body',
|
||||
initial: 'meta',
|
||||
},
|
||||
{id: 'meta', group: 'sheet', label: 'Meta'},
|
||||
{id: 'variants', group: 'sheet', label: 'Varianten'},
|
||||
{id: 'commonality', group: 'sheet', label: 'Verbreitung'},
|
||||
],
|
||||
});
|
||||
initial: 'meta'
|
||||
}
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
static PARTS = {
|
||||
form: {
|
||||
template: `systems/DSA_4-1/templates/item/spell/main-sheet.hbs`
|
||||
},
|
||||
meta: {
|
||||
template: `systems/DSA_4-1/templates/item/spell/tab-meta.hbs`
|
||||
},
|
||||
variants: {
|
||||
template: `systems/DSA_4-1/templates/item/spell/tab-variants.hbs`
|
||||
},
|
||||
commonality: {
|
||||
template: `systems/DSA_4-1/templates/item/spell/tab-commonality.hbs`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle form submission
|
||||
* @this {SpellSheet}
|
||||
* @param {SubmitEvent} event
|
||||
* @param {HTMLFormElement} form
|
||||
* @param {FormDataExtended} formData
|
||||
*/
|
||||
static async #onSubmitForm(event, form, formData) {
|
||||
event.preventDefault()
|
||||
|
||||
await this.document.update(formData.object) // Note: formData.object
|
||||
}
|
||||
|
||||
/** @override */
|
||||
get template() {
|
||||
return `systems/DSA_4-1/templates/item/item-spell-sheet.hbs`;
|
||||
}
|
||||
async _prepareContext(options) {
|
||||
const context = await super._prepareContext(options);
|
||||
const spellData = context.document;
|
||||
|
||||
/** @override */
|
||||
getData() {
|
||||
// Retrieve the data structure from the base sheet. You can inspect or log
|
||||
// the context variable to see the structure, but some key properties for
|
||||
// sheets are the actor object, the data object, whether or not it's
|
||||
// editable, the items array, and the effects array.
|
||||
const context = super.getData();
|
||||
|
||||
// Use a safe clone of the actor data for further operations.
|
||||
const skillData = context.data;
|
||||
|
||||
// Add the actor's data to context.data for easier access, as well as flags.
|
||||
context.system = skillData.system;
|
||||
context.flags = skillData.flags;
|
||||
context.system = spellData.system;
|
||||
context.flags = spellData.flags;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
// Everything below here is only needed if the sheet is editable
|
||||
if (!this.isEditable) return;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
export class VornachteilSheet extends foundry.appv1.sheets.ItemSheet {
|
||||
/**@override */
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ['dsa41', 'sheet', 'item', 'advantage'],
|
||||
width: 520,
|
||||
height: 480,
|
||||
tabs: [
|
||||
{
|
||||
navSelector: '.sheet-tabs',
|
||||
contentSelector: '.sheet-body',
|
||||
initial: 'description',
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
/** @override */
|
||||
get template() {
|
||||
return `systems/DSA_4-1/templates/item/item-advantage-sheet.hbs`;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
getData() {
|
||||
// Retrieve the data structure from the base sheet. You can inspect or log
|
||||
// the context variable to see the structure, but some key properties for
|
||||
// sheets are the actor object, the data object, whether or not it's
|
||||
// editable, the items array, and the effects array.
|
||||
const context = super.getData();
|
||||
|
||||
// Use a safe clone of the actor data for further operations.
|
||||
const advantageData = context.data;
|
||||
|
||||
// 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.hasModality = context.system.value != null
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
// Everything below here is only needed if the sheet is editable
|
||||
if (!this.isEditable) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
import {LiturgyData} from "../data/miracle/liturgydata.mjs";
|
||||
import {BlessingDataModel} from "../data/blessing.mjs";
|
||||
import {Blessing} from "../documents/blessing.mjs";
|
||||
import {Profession} from "../documents/profession.mjs";
|
||||
import {Culture} from "../documents/culture.mjs";
|
||||
import {Species} from "../documents/species.mjs";
|
||||
|
||||
let months = [
|
||||
"Praios",
|
||||
|
|
@ -18,20 +20,48 @@ let months = [
|
|||
"Namenloser Tag"
|
||||
]
|
||||
|
||||
/**
|
||||
* @typedef ImportOptions
|
||||
* @property {Boolean} skipSpecies
|
||||
* @property {Boolean} skipCulture
|
||||
* @property {Boolean} skipProfessions
|
||||
* @property {Boolean} skipAdvantages
|
||||
* @property {Boolean} skipSpecialAbilities
|
||||
* @property {Boolean} skipEquipment
|
||||
* @property {Boolean} skipSpells
|
||||
* @property {Boolean} skipLiturgies
|
||||
* @property {Boolean} skipSkills
|
||||
**/
|
||||
|
||||
/**
|
||||
* Imports a character from a file created in the tool Helden-Software
|
||||
* @param actorId the actor-id of the character
|
||||
* @param file the file from which the character should be imported
|
||||
* @param {ImportOptions?} options the set of item types the import should skip
|
||||
*/
|
||||
export async function importCharacter(actorId, file) {
|
||||
export async function importCharacter(actorId, file, options = undefined) {
|
||||
let actor = game.actors.get(actorId)
|
||||
let xmlString = await parseFileToString(file)
|
||||
let domParser = new DOMParser()
|
||||
let dom = domParser.parseFromString(xmlString, 'application/xml')
|
||||
|
||||
let rawJson = getJsonFromXML(dom)
|
||||
let characterJson = mapRawJson(actor, rawJson)
|
||||
|
||||
if (!options) {
|
||||
options = {
|
||||
skipSpecies: false,
|
||||
skipCulture: false,
|
||||
skipProfessions: false,
|
||||
skipAdvantages: false,
|
||||
skipSpecialAbilities: false,
|
||||
skipEquipment: false,
|
||||
skipSkills: false,
|
||||
skipSpells: false,
|
||||
skipLiturgies: false
|
||||
}
|
||||
}
|
||||
|
||||
let characterJson = mapRawJson(actor, rawJson, options)
|
||||
|
||||
actor.update(characterJson)
|
||||
}
|
||||
|
|
@ -74,6 +104,38 @@ function getJsonFromXML(dom) {
|
|||
return jsonResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the text content of a file
|
||||
* @param file the file with the desired content
|
||||
* @returns {Promise<String>} a promise that returns the string contents of the file
|
||||
*/
|
||||
async function parseFileToString(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let reader = new FileReader()
|
||||
reader.readAsText(file, "utf-8")
|
||||
reader.onload = event => {
|
||||
resolve(event.target.result)
|
||||
}
|
||||
reader.onerror = event => {
|
||||
reject(event)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
*Calculates a Birthdate String in the Calendar of Bosparans Fall
|
||||
* @param json json with the day, the month and the year of the birthday
|
||||
* @returns {string} a string in the format of "DD.MMMM.YYYY BF"
|
||||
*/
|
||||
function calculateBirthdate(json) {
|
||||
let day = json.gbtag
|
||||
let month = months[parseInt(json.gbmonat) - 1]
|
||||
let year = json.gbjahr
|
||||
|
||||
return `${day}. ${month} ${year} BF`
|
||||
}
|
||||
|
||||
|
||||
async function addSkillFromCompendiumByNameToActor(talentName, taw, actor, combatStatistics, attributes) {
|
||||
const compendiumOfSkills = game.packs.get('DSA_4-1.talente');
|
||||
const talentId = compendiumOfSkills.index.find(skill => skill.name === talentName)
|
||||
|
|
@ -121,6 +183,7 @@ 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)
|
||||
|
|
@ -154,38 +217,17 @@ async function addLiturgiesFromCompendiumByNameToActor(liturgyName, actor) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the text content of a file
|
||||
* @param file the file with the desired content
|
||||
* @returns {Promise<String>} a promise that returns the string contents of the file
|
||||
*/
|
||||
async function parseFileToString(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let reader = new FileReader()
|
||||
reader.readAsText(file, "utf-8")
|
||||
reader.onload = event => {
|
||||
resolve(event.target.result)
|
||||
}
|
||||
reader.onerror = event => {
|
||||
reject(event)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
*Calculates a Birthdate String in the Calendar of Bosparans Fall
|
||||
* @param json json with the day, the month and the year of the birthday
|
||||
* @returns {string} a string in the format of "DD.MMMM.YYYY BF"
|
||||
*/
|
||||
function calculateBirthdate(json) {
|
||||
let day = json.gbtag
|
||||
let month = months[parseInt(json.gbmonat) - 1]
|
||||
let year = json.gbjahr
|
||||
|
||||
return `${day}. ${month} ${year} BF`
|
||||
}
|
||||
|
||||
function mapSkills(actor, held, kampfwerte) {
|
||||
if (actor.itemTypes["Skill"].length > 0) {
|
||||
actor.itemTypes["Skill"].forEach(s => {
|
||||
actor.items.get(s._id).delete()
|
||||
})
|
||||
}
|
||||
if (actor.itemTypes["Blessing"].length > 0) {
|
||||
actor.itemTypes["Blessing"].forEach(p => {
|
||||
actor.items.get(p._id).delete()
|
||||
})
|
||||
}
|
||||
for (let talent in held.talentliste.talent) {
|
||||
talent = held.talentliste.talent[talent]
|
||||
|
||||
|
|
@ -212,6 +254,11 @@ function mapSkills(actor, held, kampfwerte) {
|
|||
}
|
||||
|
||||
function mapAdvantages(actor, held) {
|
||||
if (actor.itemTypes["Advantage"].length > 0) {
|
||||
actor.itemTypes["Advantage"].forEach(a => {
|
||||
actor.items.get(a._id).delete()
|
||||
})
|
||||
}
|
||||
for (let advantage in held.vt.vorteil) {
|
||||
advantage = held.vt.vorteil[advantage]
|
||||
addAdvantageFromCompendiumByNameToActor(advantage.name, advantage.value, actor)
|
||||
|
|
@ -219,42 +266,134 @@ function mapAdvantages(actor, held) {
|
|||
}
|
||||
|
||||
function mapSpells(actor, held) {
|
||||
if (actor.itemTypes["Spell"].length > 0) {
|
||||
actor.itemTypes["Spell"].forEach(s => {
|
||||
actor.items.get(s._id).delete()
|
||||
})
|
||||
}
|
||||
for (let spell in held.zauberliste.zauber) {
|
||||
spell = held.zauberliste.zauber[spell]
|
||||
addSpellsFromCompendiumByNameToActor(spell.name, spell.value, spell.repraesentation, spell.hauszauber === "true", actor)
|
||||
}
|
||||
}
|
||||
|
||||
function mapMiracles(actor, liturgies) {
|
||||
function mapLiturgies(actor, liturgies) {
|
||||
if (actor.itemTypes["Liturgy"].length > 0) {
|
||||
actor.itemTypes["Liturgy"].forEach(l => {
|
||||
actor.items.get(l._id).delete()
|
||||
})
|
||||
}
|
||||
for (let liturgy in liturgies) {
|
||||
liturgy = liturgies[liturgy]
|
||||
addLiturgiesFromCompendiumByNameToActor(liturgy.name, actor)
|
||||
}
|
||||
}
|
||||
|
||||
async function mapProfessions(actor, professions) {
|
||||
if (actor.itemTypes["Profession"].length > 0) {
|
||||
actor.itemTypes["Profession"].forEach(p => {
|
||||
actor.items.get(p._id).delete()
|
||||
})
|
||||
}
|
||||
if (professions.string) {
|
||||
professions = {hauptprofession: professions}
|
||||
}
|
||||
Object.values(professions).forEach(profession => {
|
||||
actor.createEmbeddedDocuments('Item', [
|
||||
new Profession({
|
||||
name: profession.string,
|
||||
type: "Profession",
|
||||
system: {
|
||||
description: "",
|
||||
alias: profession.tarnidentitaet ? profession.tarnidentitaet : profession.string,
|
||||
revealed: !profession.tarnidentitaet
|
||||
}
|
||||
})
|
||||
])
|
||||
})
|
||||
// actor.update({"system.meta.professions": professions})
|
||||
}
|
||||
|
||||
async function mapSpezies(actor, spezies) {
|
||||
if (actor.itemTypes["Species"].length > 0) {
|
||||
actor.itemTypes["Species"].forEach(s => {
|
||||
actor.items.get(s._id).delete()
|
||||
})
|
||||
}
|
||||
const compendiumOfSpecies = game.packs.get('DSA_4-1.spezien');
|
||||
const speciesId = compendiumOfSpecies?.index.find(species => species.name === spezies.name)
|
||||
|
||||
if (speciesId) {
|
||||
const species =
|
||||
await compendiumOfSpecies.getDocument(speciesId);
|
||||
try {
|
||||
await actor.createEmbeddedDocuments('Item', [species])
|
||||
} catch (e) {
|
||||
}
|
||||
} else {
|
||||
actor.createEmbeddedDocuments('Item', [
|
||||
new Species({
|
||||
name: spezies.name,
|
||||
type: "Species",
|
||||
system: {
|
||||
feminineDemonym: spezies.string,
|
||||
masculineDemonym: spezies.string,
|
||||
description: "Importiert",
|
||||
}
|
||||
})
|
||||
])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async function mapKultur(actor, kultur) {
|
||||
if (actor.itemTypes["Culture"].length > 0) {
|
||||
actor.itemTypes["Culture"].forEach(c => {
|
||||
actor.items.get(c._id).delete()
|
||||
})
|
||||
}
|
||||
const compendiumOfCultures = game.packs.get('DSA_4-1.kulturen');
|
||||
const cultureId = compendiumOfCultures?.index.find(culture => culture.name === kultur.name)
|
||||
|
||||
if (cultureId) {
|
||||
const culture =
|
||||
await compendiumOfCultures.getDocument(cultureId);
|
||||
try {
|
||||
await actor.createEmbeddedDocuments('Item', [culture])
|
||||
} catch (e) {
|
||||
}
|
||||
} else {
|
||||
actor.createEmbeddedDocuments('Item', [
|
||||
new Culture({
|
||||
name: kultur.name,
|
||||
type: "Culture",
|
||||
system: {
|
||||
variant: kultur.variante.name ?? "",
|
||||
feminineDemonym: kultur.string,
|
||||
masculineDemonym: kultur.string,
|
||||
description: "Importiert",
|
||||
}
|
||||
})
|
||||
])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* parses a json into a fitting character-json
|
||||
* @param {Character} actor
|
||||
* @param rawJson the json parsed from the Helden-Software XML
|
||||
* @param {ImportOptions} options
|
||||
* @returns {{}} a json representation of the character
|
||||
*/
|
||||
function mapRawJson(actor, rawJson) {
|
||||
function mapRawJson(actor, rawJson, options) {
|
||||
let json = {}
|
||||
let held = rawJson.helden.held;
|
||||
json.name = held.name
|
||||
json.meta = {}
|
||||
json.meta.spezies = held.basis.rasse.string
|
||||
json.meta.kultur = held.basis.kultur.string
|
||||
let professions = []
|
||||
for (let profession in held.basis.ausbildungen.ausbildung) {
|
||||
profession = held.basis.ausbildungen.ausbildung[profession]
|
||||
if (profession.tarnidentitaet) {
|
||||
professions = [profession.tarnidentitaet]
|
||||
break;
|
||||
}
|
||||
let professionString = profession.string
|
||||
professions.push(professionString)
|
||||
}
|
||||
json.meta.professions = professions
|
||||
if (!options.skipSpecies) mapSpezies(actor, held.basis.rasse) // as string includes the demonymized form
|
||||
if (!options.skipCulture) mapKultur(actor, held.basis.kultur) // as string includes the demonymized form
|
||||
if (!options.skipProfessions) mapProfessions(actor, held.basis.ausbildungen.ausbildung)
|
||||
json.meta.geschlecht = held.basis.geschlecht.name
|
||||
json.meta.haarfarbe = held.basis.rasse.aussehen.haarfarbe
|
||||
json.meta.groesse = held.basis.rasse.groesse.value
|
||||
|
|
@ -311,7 +450,7 @@ function mapRawJson(actor, rawJson) {
|
|||
aktuell: attribute.value
|
||||
}
|
||||
json.attribute.so = getAttributeJson(attributes, "Sozialstatus")
|
||||
mapAdvantages(actor, held)
|
||||
if (!options.skipAdvantages) mapAdvantages(actor, held)
|
||||
let specialAbilities = []
|
||||
let liturgies = []
|
||||
for (let specialAbility in held.sf.sonderfertigkeit) {
|
||||
|
|
@ -359,9 +498,9 @@ function mapRawJson(actor, rawJson) {
|
|||
}
|
||||
json.kampfwerte = combatValues
|
||||
|
||||
mapSkills(actor, held, combatValues)
|
||||
mapSpells(actor, held)
|
||||
mapMiracles(actor, liturgies)
|
||||
if (!options.skipSkills) mapSkills(actor, held, combatValues)
|
||||
if (!options.skipSpells) mapSpells(actor, held)
|
||||
if (!options.skipLiturgies) mapLiturgies(actor, liturgies)
|
||||
|
||||
let notes = []
|
||||
for (let note in held.kommentare) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"name": "helden.model.kultur.Mittelreich",
|
||||
"masculineDemonym": "Mittelländische Landbevölkerung",
|
||||
"feminineDemonym": "Mittelländische Landbevölkerung",
|
||||
"description": ""
|
||||
}
|
||||
|
|
@ -2,24 +2,14 @@
|
|||
"name": "Munition (Balläster)",
|
||||
"image": "systems/DSA_4-1/assets/arsenal/arrow3.png",
|
||||
"category": [
|
||||
"Gegenstand"
|
||||
"Gegenstand",
|
||||
"Munition"
|
||||
],
|
||||
"weight": 0.125,
|
||||
"price": 0.6,
|
||||
"breakFactor": 0,
|
||||
"iniModifier": 0,
|
||||
"attackModifier": 0,
|
||||
"parryModifier": 0,
|
||||
"meleeAttackModifier": 0,
|
||||
"meleeAttackModifierIncrement": 0,
|
||||
"meleeSkills": [],
|
||||
"meleeAttackDamage": "",
|
||||
"rangedSkills": [],
|
||||
"rangedRangeModifier": "",
|
||||
"rangedRangeDamageModifier": "",
|
||||
"rangedAttackDamage": "",
|
||||
"rangedReloadTime": 0,
|
||||
"armorValue": 0,
|
||||
"armorHandicap": 0,
|
||||
"description": ""
|
||||
"description": "",
|
||||
"ammunition": {
|
||||
"max": 1,
|
||||
"count": 1
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,24 +2,14 @@
|
|||
"name": "Munition (Eisenwalder)",
|
||||
"image": "systems/DSA_4-1/assets/arsenal/arrow3.png",
|
||||
"category": [
|
||||
"Gegenstand"
|
||||
"Gegenstand",
|
||||
"Munition"
|
||||
],
|
||||
"weight": 0,
|
||||
"price": 1.5,
|
||||
"breakFactor": 0,
|
||||
"iniModifier": 0,
|
||||
"attackModifier": 0,
|
||||
"parryModifier": 0,
|
||||
"meleeAttackModifier": 0,
|
||||
"meleeAttackModifierIncrement": 0,
|
||||
"meleeSkills": [],
|
||||
"meleeAttackDamage": "",
|
||||
"rangedSkills": [],
|
||||
"rangedRangeModifier": "",
|
||||
"rangedRangeDamageModifier": "",
|
||||
"rangedAttackDamage": "",
|
||||
"rangedReloadTime": 0,
|
||||
"armorValue": 0,
|
||||
"armorHandicap": 0,
|
||||
"description": ""
|
||||
"description": "",
|
||||
"ammunition": {
|
||||
"max": 10,
|
||||
"count": 10
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,24 +2,14 @@
|
|||
"name": "Munition (Elfenbogen)",
|
||||
"image": "systems/DSA_4-1/assets/arsenal/arrow2.png",
|
||||
"category": [
|
||||
"Gegenstand"
|
||||
"Gegenstand",
|
||||
"Munition"
|
||||
],
|
||||
"weight": 0.075,
|
||||
"price": 0.4,
|
||||
"breakFactor": 0,
|
||||
"iniModifier": 0,
|
||||
"attackModifier": 0,
|
||||
"parryModifier": 0,
|
||||
"meleeAttackModifier": 0,
|
||||
"meleeAttackModifierIncrement": 0,
|
||||
"meleeSkills": [],
|
||||
"meleeAttackDamage": "",
|
||||
"rangedSkills": [],
|
||||
"rangedRangeModifier": "",
|
||||
"rangedRangeDamageModifier": "",
|
||||
"rangedAttackDamage": "",
|
||||
"rangedReloadTime": 0,
|
||||
"armorValue": 0,
|
||||
"armorHandicap": 0,
|
||||
"description": ""
|
||||
"description": "",
|
||||
"ammunition": {
|
||||
"max": 1,
|
||||
"count": 1
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,24 +2,14 @@
|
|||
"name": "Munition (Kompositbogen)",
|
||||
"image": "systems/DSA_4-1/assets/arsenal/arrow1.png",
|
||||
"category": [
|
||||
"Gegenstand"
|
||||
"Gegenstand",
|
||||
"Munition"
|
||||
],
|
||||
"weight": 0.05,
|
||||
"price": 0.25,
|
||||
"breakFactor": 0,
|
||||
"iniModifier": 0,
|
||||
"attackModifier": 0,
|
||||
"parryModifier": 0,
|
||||
"meleeAttackModifier": 0,
|
||||
"meleeAttackModifierIncrement": 0,
|
||||
"meleeSkills": [],
|
||||
"meleeAttackDamage": "",
|
||||
"rangedSkills": [],
|
||||
"rangedRangeModifier": "",
|
||||
"rangedRangeDamageModifier": "",
|
||||
"rangedAttackDamage": "",
|
||||
"rangedReloadTime": 0,
|
||||
"armorValue": 0,
|
||||
"armorHandicap": 0,
|
||||
"description": ""
|
||||
"description": "",
|
||||
"ammunition": {
|
||||
"max": 1,
|
||||
"count": 1
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,24 +2,14 @@
|
|||
"name": "Munition (Kriegsbogen)",
|
||||
"image": "systems/DSA_4-1/assets/arsenal/arrow1.png",
|
||||
"category": [
|
||||
"Gegenstand"
|
||||
"Gegenstand",
|
||||
"Munition"
|
||||
],
|
||||
"weight": 0.1,
|
||||
"price": 0.6,
|
||||
"breakFactor": 0,
|
||||
"iniModifier": 0,
|
||||
"attackModifier": 0,
|
||||
"parryModifier": 0,
|
||||
"meleeAttackModifier": 0,
|
||||
"meleeAttackModifierIncrement": 0,
|
||||
"meleeSkills": [],
|
||||
"meleeAttackDamage": "",
|
||||
"rangedSkills": [],
|
||||
"rangedRangeModifier": "",
|
||||
"rangedRangeDamageModifier": "",
|
||||
"rangedAttackDamage": "",
|
||||
"rangedReloadTime": 0,
|
||||
"armorValue": 0,
|
||||
"armorHandicap": 0,
|
||||
"description": ""
|
||||
"description": "",
|
||||
"ammunition": {
|
||||
"max": 1,
|
||||
"count": 1
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,24 +2,14 @@
|
|||
"name": "Munition (Kurzbogen)",
|
||||
"image": "systems/DSA_4-1/assets/arsenal/arrow1.png",
|
||||
"category": [
|
||||
"Gegenstand"
|
||||
"Gegenstand",
|
||||
"Munition"
|
||||
],
|
||||
"weight": 0.05,
|
||||
"price": 0.25,
|
||||
"breakFactor": 0,
|
||||
"iniModifier": 0,
|
||||
"attackModifier": 0,
|
||||
"parryModifier": 0,
|
||||
"meleeAttackModifier": 0,
|
||||
"meleeAttackModifierIncrement": 0,
|
||||
"meleeSkills": [],
|
||||
"meleeAttackDamage": "",
|
||||
"rangedSkills": [],
|
||||
"rangedRangeModifier": "",
|
||||
"rangedRangeDamageModifier": "",
|
||||
"rangedAttackDamage": "",
|
||||
"rangedReloadTime": 0,
|
||||
"armorValue": 0,
|
||||
"armorHandicap": 0,
|
||||
"description": ""
|
||||
"description": "",
|
||||
"ammunition": {
|
||||
"max": 1,
|
||||
"count": 1
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,24 +2,14 @@
|
|||
"name": "Munition (Langbogen)",
|
||||
"image": "systems/DSA_4-1/assets/arsenal/arrow1.png",
|
||||
"category": [
|
||||
"Gegenstand"
|
||||
"Gegenstand",
|
||||
"Munition"
|
||||
],
|
||||
"weight": 0.075,
|
||||
"price": 0.4,
|
||||
"breakFactor": 0,
|
||||
"iniModifier": 0,
|
||||
"attackModifier": 0,
|
||||
"parryModifier": 0,
|
||||
"meleeAttackModifier": 0,
|
||||
"meleeAttackModifierIncrement": 0,
|
||||
"meleeSkills": [],
|
||||
"meleeAttackDamage": "",
|
||||
"rangedSkills": [],
|
||||
"rangedRangeModifier": "",
|
||||
"rangedRangeDamageModifier": "",
|
||||
"rangedAttackDamage": "",
|
||||
"rangedReloadTime": 0,
|
||||
"armorValue": 0,
|
||||
"armorHandicap": 0,
|
||||
"description": ""
|
||||
"description": "",
|
||||
"ammunition": {
|
||||
"max": 1,
|
||||
"count": 1
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,24 +2,14 @@
|
|||
"name": "Munition (Leichte Armbrust)",
|
||||
"image": "systems/DSA_4-1/assets/arsenal/arrow3.png",
|
||||
"category": [
|
||||
"Gegenstand"
|
||||
"Gegenstand",
|
||||
"Munition"
|
||||
],
|
||||
"weight": 0.075,
|
||||
"price": 1.5,
|
||||
"breakFactor": 0,
|
||||
"iniModifier": 0,
|
||||
"attackModifier": 0,
|
||||
"parryModifier": 0,
|
||||
"meleeAttackModifier": 0,
|
||||
"meleeAttackModifierIncrement": 0,
|
||||
"meleeSkills": [],
|
||||
"meleeAttackDamage": "",
|
||||
"rangedSkills": [],
|
||||
"rangedRangeModifier": "",
|
||||
"rangedRangeDamageModifier": "",
|
||||
"rangedAttackDamage": "",
|
||||
"rangedReloadTime": 0,
|
||||
"armorValue": 0,
|
||||
"armorHandicap": 0,
|
||||
"description": ""
|
||||
"description": "",
|
||||
"ammunition": {
|
||||
"max": 1,
|
||||
"count": 1
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,24 +2,14 @@
|
|||
"name": "Munition (Windenarmbrust)",
|
||||
"image": "systems/DSA_4-1/assets/arsenal/arrow3.png",
|
||||
"category": [
|
||||
"Gegenstand"
|
||||
"Gegenstand",
|
||||
"Munition"
|
||||
],
|
||||
"weight": 0.1,
|
||||
"price": 2,
|
||||
"breakFactor": 0,
|
||||
"iniModifier": 0,
|
||||
"attackModifier": 0,
|
||||
"parryModifier": 0,
|
||||
"meleeAttackModifier": 0,
|
||||
"meleeAttackModifierIncrement": 0,
|
||||
"meleeSkills": [],
|
||||
"meleeAttackDamage": "",
|
||||
"rangedSkills": [],
|
||||
"rangedRangeModifier": "",
|
||||
"rangedRangeDamageModifier": "",
|
||||
"rangedAttackDamage": "",
|
||||
"rangedReloadTime": 0,
|
||||
"armorValue": 0,
|
||||
"armorHandicap": 0,
|
||||
"description": ""
|
||||
"description": "",
|
||||
"ammunition": {
|
||||
"max": 1,
|
||||
"count": 1
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,21 +8,13 @@
|
|||
"weight": 1,
|
||||
"price": 40,
|
||||
"breakFactor": 0,
|
||||
"iniModifier": 0,
|
||||
"attackModifier": 0,
|
||||
"parryModifier": 1,
|
||||
"iniModifier": -1,
|
||||
"attackModifier": -2,
|
||||
"parryModifier": -1,
|
||||
"meleeAttackModifier": 0,
|
||||
"meleeAttackModifierIncrement": 0,
|
||||
"meleeSkills": [
|
||||
"Schilde"
|
||||
],
|
||||
"meleeAttackDamage": "",
|
||||
"rangedSkills": [],
|
||||
"rangedRangeModifier": "",
|
||||
"rangedRangeDamageModifier": "",
|
||||
"rangedAttackDamage": "",
|
||||
"rangedReloadTime": 0,
|
||||
"armorValue": 1,
|
||||
"armorHandicap": 1,
|
||||
"description": ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,20 +7,17 @@
|
|||
],
|
||||
"weight": 3,
|
||||
"price": 0,
|
||||
"breakFactor": 0,
|
||||
"iniModifier": 0,
|
||||
"attackModifier": 0,
|
||||
"parryModifier": 0,
|
||||
"meleeAttackModifier": 0,
|
||||
"meleeAttackModifierIncrement": 0,
|
||||
"meleeSkills": [],
|
||||
"meleeAttackDamage": "",
|
||||
"rangedSkills": [],
|
||||
"rangedRangeModifier": "",
|
||||
"rangedRangeDamageModifier": "",
|
||||
"rangedAttackDamage": "",
|
||||
"rangedReloadTime": 0,
|
||||
"armorValue": 1,
|
||||
"armorValue": {
|
||||
"total": 1,
|
||||
"kopf": 0,
|
||||
"brust": 1,
|
||||
"ruecken": 1,
|
||||
"bauch": 1,
|
||||
"armlinks": 1,
|
||||
"beinlinks": 1,
|
||||
"armrechts": 1,
|
||||
"beinrechts": 1
|
||||
},
|
||||
"armorHandicap": 1,
|
||||
"description": ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,20 +7,17 @@
|
|||
],
|
||||
"weight": 14,
|
||||
"price": 750,
|
||||
"breakFactor": 0,
|
||||
"iniModifier": 0,
|
||||
"attackModifier": 0,
|
||||
"parryModifier": 0,
|
||||
"meleeAttackModifier": 0,
|
||||
"meleeAttackModifierIncrement": 0,
|
||||
"meleeSkills": [],
|
||||
"meleeAttackDamage": "",
|
||||
"rangedSkills": [],
|
||||
"rangedRangeModifier": "",
|
||||
"rangedRangeDamageModifier": "",
|
||||
"rangedAttackDamage": "",
|
||||
"rangedReloadTime": 0,
|
||||
"armorValue": 6,
|
||||
"armorValue": {
|
||||
"total": 5,
|
||||
"kopf": 0,
|
||||
"brust": 6,
|
||||
"ruecken": 5,
|
||||
"bauch": 6,
|
||||
"armlinks": 5,
|
||||
"armrechts": 5,
|
||||
"beinlinks": 4,
|
||||
"beinrechts": 4
|
||||
},
|
||||
"armorHandicap": 4,
|
||||
"description": ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,20 +7,17 @@
|
|||
],
|
||||
"weight": 17,
|
||||
"price": 1000,
|
||||
"breakFactor": 0,
|
||||
"iniModifier": 0,
|
||||
"attackModifier": 0,
|
||||
"parryModifier": 0,
|
||||
"meleeAttackModifier": 0,
|
||||
"meleeAttackModifierIncrement": 0,
|
||||
"meleeSkills": [],
|
||||
"meleeAttackDamage": "",
|
||||
"rangedSkills": [],
|
||||
"rangedRangeModifier": "",
|
||||
"rangedRangeDamageModifier": "",
|
||||
"rangedAttackDamage": "",
|
||||
"rangedReloadTime": 0,
|
||||
"armorValue": 8,
|
||||
"armorHandicap": 5,
|
||||
"armorValue": {
|
||||
"total": 6,
|
||||
"kopf": 3,
|
||||
"brust": 7,
|
||||
"ruecken": 5,
|
||||
"bauch": 7,
|
||||
"armlinks": 5,
|
||||
"beinlinks": 5,
|
||||
"armrechts": 5,
|
||||
"beinrechts": 5
|
||||
},
|
||||
"armorHandicap": 4,
|
||||
"description": ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,20 +7,17 @@
|
|||
],
|
||||
"weight": 6.5,
|
||||
"price": 150,
|
||||
"breakFactor": 0,
|
||||
"iniModifier": 0,
|
||||
"attackModifier": 0,
|
||||
"parryModifier": 0,
|
||||
"meleeAttackModifier": 0,
|
||||
"meleeAttackModifierIncrement": 0,
|
||||
"meleeSkills": [],
|
||||
"meleeAttackDamage": "",
|
||||
"rangedSkills": [],
|
||||
"rangedRangeModifier": "",
|
||||
"rangedRangeDamageModifier": "",
|
||||
"rangedAttackDamage": "",
|
||||
"rangedReloadTime": 0,
|
||||
"armorValue": 3,
|
||||
"armorHandicap": 3,
|
||||
"armorValue": {
|
||||
"total": 3,
|
||||
"kopf": 0,
|
||||
"brust": 4,
|
||||
"ruecken": 4,
|
||||
"bauch": 4,
|
||||
"armlinks": 2,
|
||||
"armrechts": 2,
|
||||
"beinlinks": 1,
|
||||
"beinrechts": 1
|
||||
},
|
||||
"armorHandicap": 2,
|
||||
"description": ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,20 +7,17 @@
|
|||
],
|
||||
"weight": 30,
|
||||
"price": 2500,
|
||||
"breakFactor": 0,
|
||||
"iniModifier": 0,
|
||||
"attackModifier": 0,
|
||||
"parryModifier": 0,
|
||||
"meleeAttackModifier": 0,
|
||||
"meleeAttackModifierIncrement": 0,
|
||||
"meleeSkills": [],
|
||||
"meleeAttackDamage": "",
|
||||
"rangedSkills": [],
|
||||
"rangedRangeModifier": "",
|
||||
"rangedRangeDamageModifier": "",
|
||||
"rangedAttackDamage": "",
|
||||
"rangedReloadTime": 0,
|
||||
"armorValue": 12,
|
||||
"armorHandicap": 10,
|
||||
"armorValue": {
|
||||
"total": 8,
|
||||
"kopf": 8,
|
||||
"brust": 8,
|
||||
"ruecken": 7,
|
||||
"bauch": 8,
|
||||
"armlinks": 7,
|
||||
"beinlinks": 7,
|
||||
"armrechts": 7,
|
||||
"beinrechts": 7
|
||||
},
|
||||
"armorHandicap": 8,
|
||||
"description": ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,20 +7,17 @@
|
|||
],
|
||||
"weight": 4,
|
||||
"price": 60,
|
||||
"breakFactor": 0,
|
||||
"iniModifier": 0,
|
||||
"attackModifier": 0,
|
||||
"parryModifier": 0,
|
||||
"meleeAttackModifier": 0,
|
||||
"meleeAttackModifierIncrement": 0,
|
||||
"meleeSkills": [],
|
||||
"meleeAttackDamage": "",
|
||||
"rangedSkills": [],
|
||||
"rangedRangeModifier": "",
|
||||
"rangedRangeDamageModifier": "",
|
||||
"rangedAttackDamage": "",
|
||||
"rangedReloadTime": 0,
|
||||
"armorValue": 3,
|
||||
"armorValue": {
|
||||
"total": 2,
|
||||
"kopf": 0,
|
||||
"brust": 3,
|
||||
"ruecken": 2,
|
||||
"bauch": 2,
|
||||
"armlinks": 1,
|
||||
"beinlinks": 0,
|
||||
"armrechts": 1,
|
||||
"beinrechts": 0
|
||||
},
|
||||
"armorHandicap": 2,
|
||||
"description": ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,20 +7,17 @@
|
|||
],
|
||||
"weight": 4,
|
||||
"price": 110,
|
||||
"breakFactor": 0,
|
||||
"iniModifier": 0,
|
||||
"attackModifier": 0,
|
||||
"parryModifier": 0,
|
||||
"meleeAttackModifier": 0,
|
||||
"meleeAttackModifierIncrement": 0,
|
||||
"meleeSkills": [],
|
||||
"meleeAttackDamage": "",
|
||||
"rangedSkills": [],
|
||||
"rangedRangeModifier": "",
|
||||
"rangedRangeDamageModifier": "",
|
||||
"rangedAttackDamage": "",
|
||||
"rangedReloadTime": 0,
|
||||
"armorValue": 3,
|
||||
"armorHandicap": 2,
|
||||
"armorValue": {
|
||||
"total": 2,
|
||||
"kopf": 0,
|
||||
"brust": 5,
|
||||
"ruecken": 1,
|
||||
"bauch": 2,
|
||||
"armlinks": 0,
|
||||
"beinlinks": 0,
|
||||
"armrechts": 0,
|
||||
"beinrechts": 0
|
||||
},
|
||||
"armorHandicap": 1,
|
||||
"description": ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,20 +7,17 @@
|
|||
],
|
||||
"weight": 10,
|
||||
"price": 180,
|
||||
"breakFactor": 0,
|
||||
"iniModifier": 0,
|
||||
"attackModifier": 0,
|
||||
"parryModifier": 0,
|
||||
"meleeAttackModifier": 0,
|
||||
"meleeAttackModifierIncrement": 0,
|
||||
"meleeSkills": [],
|
||||
"meleeAttackDamage": "",
|
||||
"rangedSkills": [],
|
||||
"rangedRangeModifier": "",
|
||||
"rangedRangeDamageModifier": "",
|
||||
"rangedAttackDamage": "",
|
||||
"rangedReloadTime": 0,
|
||||
"armorValue": 4,
|
||||
"armorHandicap": 4,
|
||||
"armorValue": {
|
||||
"total": 3,
|
||||
"kopf": 0,
|
||||
"brust": 4,
|
||||
"ruecken": 4,
|
||||
"bauch": 4,
|
||||
"armlinks": 3,
|
||||
"armrechts": 3,
|
||||
"beinlinks": 2,
|
||||
"beinrechts": 2
|
||||
},
|
||||
"armorHandicap": 2,
|
||||
"description": ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,20 +7,17 @@
|
|||
],
|
||||
"weight": 4.5,
|
||||
"price": 80,
|
||||
"breakFactor": 0,
|
||||
"iniModifier": 0,
|
||||
"attackModifier": 0,
|
||||
"parryModifier": 0,
|
||||
"meleeAttackModifier": 0,
|
||||
"meleeAttackModifierIncrement": 0,
|
||||
"meleeSkills": [],
|
||||
"meleeAttackDamage": "",
|
||||
"rangedSkills": [],
|
||||
"rangedRangeModifier": "",
|
||||
"rangedRangeDamageModifier": "",
|
||||
"rangedAttackDamage": "",
|
||||
"rangedReloadTime": 0,
|
||||
"armorValue": 3,
|
||||
"armorHandicap": 3,
|
||||
"armorValue": {
|
||||
"total": 2,
|
||||
"kopf": 0,
|
||||
"brust": 3,
|
||||
"ruecken": 3,
|
||||
"bauch": 3,
|
||||
"armlinks": 0,
|
||||
"beinlinks": 0,
|
||||
"armrechts": 0,
|
||||
"beinrechts": 0
|
||||
},
|
||||
"armorHandicap": 1,
|
||||
"description": ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,20 +7,17 @@
|
|||
],
|
||||
"weight": 7.5,
|
||||
"price": 250,
|
||||
"breakFactor": 0,
|
||||
"iniModifier": 0,
|
||||
"attackModifier": 0,
|
||||
"parryModifier": 0,
|
||||
"meleeAttackModifier": 0,
|
||||
"meleeAttackModifierIncrement": 0,
|
||||
"meleeSkills": [],
|
||||
"meleeAttackDamage": "",
|
||||
"rangedSkills": [],
|
||||
"rangedRangeModifier": "",
|
||||
"rangedRangeDamageModifier": "",
|
||||
"rangedAttackDamage": "",
|
||||
"rangedReloadTime": 0,
|
||||
"armorValue": 4,
|
||||
"armorHandicap": 3,
|
||||
"armorValue": {
|
||||
"total": 3,
|
||||
"kopf": 0,
|
||||
"brust": 5,
|
||||
"ruecken": 4,
|
||||
"bauch": 5,
|
||||
"armlinks": 0,
|
||||
"armrechts": 0,
|
||||
"beinlinks": 2,
|
||||
"beinrechts": 2
|
||||
},
|
||||
"armorHandicap": 2,
|
||||
"description": ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,20 +7,17 @@
|
|||
],
|
||||
"weight": 12,
|
||||
"price": 1000,
|
||||
"breakFactor": 0,
|
||||
"iniModifier": 0,
|
||||
"attackModifier": 0,
|
||||
"parryModifier": 0,
|
||||
"meleeAttackModifier": 0,
|
||||
"meleeAttackModifierIncrement": 0,
|
||||
"meleeSkills": [],
|
||||
"meleeAttackDamage": "",
|
||||
"rangedSkills": [],
|
||||
"rangedRangeModifier": "",
|
||||
"rangedRangeDamageModifier": "",
|
||||
"rangedAttackDamage": "",
|
||||
"rangedReloadTime": 0,
|
||||
"armorValue": 5,
|
||||
"armorHandicap": 5,
|
||||
"armorValue": {
|
||||
"total": 4,
|
||||
"kopf": 0,
|
||||
"brust": 5,
|
||||
"ruecken": 5,
|
||||
"bauch": 5,
|
||||
"armlinks": 3,
|
||||
"beinlinks": 3,
|
||||
"armrechts": 3,
|
||||
"beinrechts": 3
|
||||
},
|
||||
"armorHandicap": 4,
|
||||
"description": ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,20 +7,17 @@
|
|||
],
|
||||
"weight": 10,
|
||||
"price": 1000,
|
||||
"breakFactor": 0,
|
||||
"iniModifier": 0,
|
||||
"attackModifier": 0,
|
||||
"parryModifier": 0,
|
||||
"meleeAttackModifier": 0,
|
||||
"meleeAttackModifierIncrement": 0,
|
||||
"meleeSkills": [],
|
||||
"meleeAttackDamage": "",
|
||||
"rangedSkills": [],
|
||||
"rangedRangeModifier": "",
|
||||
"rangedRangeDamageModifier": "",
|
||||
"rangedAttackDamage": "",
|
||||
"rangedReloadTime": 0,
|
||||
"armorValue": 5,
|
||||
"armorHandicap": 4,
|
||||
"armorValue": {
|
||||
"total": 4,
|
||||
"kopf": 0,
|
||||
"brust": 5,
|
||||
"ruecken": 5,
|
||||
"bauch": 5,
|
||||
"armlinks": 3,
|
||||
"armrechts": 3,
|
||||
"beinlinks": 2,
|
||||
"beinrechts": 2
|
||||
},
|
||||
"armorHandicap": 3,
|
||||
"description": ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,17 @@
|
|||
"rangedRangeDamageModifier": "",
|
||||
"rangedAttackDamage": "",
|
||||
"rangedReloadTime": 0,
|
||||
"armorValue": 1,
|
||||
"armorValue": {
|
||||
"total": 1.5,
|
||||
"kopf": 0,
|
||||
"brust": 1,
|
||||
"ruecken": 1,
|
||||
"bauch": 1,
|
||||
"armlinks": 1,
|
||||
"beinlinks": 1,
|
||||
"armrechts": 1,
|
||||
"beinrechts": 1
|
||||
},
|
||||
"armorHandicap": 1,
|
||||
"description": ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,20 +7,17 @@
|
|||
],
|
||||
"weight": 3,
|
||||
"price": 40,
|
||||
"breakFactor": 0,
|
||||
"iniModifier": 0,
|
||||
"attackModifier": 0,
|
||||
"parryModifier": 0,
|
||||
"meleeAttackModifier": 0,
|
||||
"meleeAttackModifierIncrement": 0,
|
||||
"meleeSkills": [],
|
||||
"meleeAttackDamage": "",
|
||||
"rangedSkills": [],
|
||||
"rangedRangeModifier": "",
|
||||
"rangedRangeDamageModifier": "",
|
||||
"rangedAttackDamage": "",
|
||||
"rangedReloadTime": 0,
|
||||
"armorValue": 2,
|
||||
"armorValue": {
|
||||
"total": 2,
|
||||
"kopf": 0,
|
||||
"brust": 2,
|
||||
"ruecken": 2,
|
||||
"bauch": 2,
|
||||
"armlinks": 1,
|
||||
"beinlinks": 1,
|
||||
"armrechts": 1,
|
||||
"beinrechts": 1
|
||||
},
|
||||
"armorHandicap": 2,
|
||||
"description": ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "helden.model.rasse.Mittellaender",
|
||||
"masculineDemonym": "Mittelländer",
|
||||
"feminineDemonym": "Mittelländerin",
|
||||
"description": "",
|
||||
"baseSpeed": 6
|
||||
}
|
||||
|
|
@ -1,7 +1,11 @@
|
|||
{
|
||||
"seite": "287",
|
||||
"name": "WINDSTILLE",
|
||||
"probe": ["KL", "CH", "KK"],
|
||||
"probe": [
|
||||
"KL",
|
||||
"CH",
|
||||
"KK"
|
||||
],
|
||||
"technik": "Der Elf formt die Hände über seinem Kopf zu einem Dach, spricht 'rongra sala bian'dao' und breitet die Arme aus.",
|
||||
"zauberdauer": "30 Aktionen",
|
||||
"wirkung": "Der Zauber erschafft eine Zone völliger Windstille, unabhängig von der Windstärke außerhalb. Diese Zone bewegt sich mit dem Elfen. Innerhalb dieser Zone steht die Luft still – selbst Blätter und Rauch verharren. Geräusche tragen schlechter, Pfeile und Geschosse verlieren an Reichweite, und fliegende Wesen haben Mühe, sich zu bewegen. Die Zauberprobe ist um die aktuelle Windstärke (nach Beaufort-Skala) erschwert. Der Effekt wirkt bis zur Windstärke 12 (Orkan).",
|
||||
|
|
@ -29,7 +33,10 @@
|
|||
},
|
||||
"reversalis": "Jede Luftbewegung innerhalb der Zone wird um ZfP*/2 Windstärken verstärkt, sodass schon ein leichtes Blasen einen kräftigen Wind erzeugen kann. Diese Variante kostet 10 AsP pro Spielrunde.",
|
||||
"antimagie": "VERÄNDERUNG AUFHEBEN oder LUFTBANN können den Zauber schwächen oder beenden. Befindet sich die Zone in einem Sturm, kann dieser abgeschwächt, aber nicht aufgehoben werden.",
|
||||
"merkmal": ["Elementar (Luft)", "Umwelt"],
|
||||
"merkmal": [
|
||||
"Elementar (Luft)",
|
||||
"Umwelt"
|
||||
],
|
||||
"komplexität": "C",
|
||||
"repräsentation": "Elf 6, Mag, Dru (Mag) je 2",
|
||||
"info": "WINDSTILLE gilt als Teil einer Hexalogie des Banns elementarer Gewalten, die vermutlich von el"
|
||||
|
|
|
|||
|
|
@ -1,95 +0,0 @@
|
|||
@use "./_colours";
|
||||
@use "./_numbers";
|
||||
@use "./_assets";
|
||||
@use "sass:color";
|
||||
|
||||
.dsa41.sheet.actor.character {
|
||||
|
||||
.sheet-header {
|
||||
position: relative;
|
||||
|
||||
.attributes {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 4px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
|
||||
.attribute.rollable {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
position: relative;
|
||||
box-shadow: inset numbers.$dice-box-inset numbers.$dice-box-inset numbers.$dice-box-blur-radius colours.$dice-box-shadow;
|
||||
background: assets.$dice-box-background;
|
||||
margin-left: 2px;
|
||||
border: numbers.$dice-box-border-width inset colours.$dice-box-border-color;
|
||||
|
||||
.die {
|
||||
stroke-width: 0.5;
|
||||
|
||||
svg {
|
||||
position: absolute;
|
||||
left: 4px;
|
||||
top: 4px;
|
||||
bottom: 4px;
|
||||
right: 4px;
|
||||
}
|
||||
|
||||
.border {
|
||||
fill: rgba(0, 0, 0, 0);
|
||||
stroke: colours.$attribute-die-border-color;
|
||||
}
|
||||
|
||||
.center {
|
||||
fill: colours.$attribute-die-color;
|
||||
stroke: colours.$attribute-die-border-color;
|
||||
}
|
||||
|
||||
.topleft {
|
||||
fill: color.adjust(colours.$attribute-die-color, $lightness: numbers.$lighter_factor);
|
||||
stroke: colours.$attribute-die-border-color;
|
||||
}
|
||||
|
||||
.bottomleft {
|
||||
fill: color.adjust(colours.$attribute-die-color, $lightness: numbers.$lightest_factor);
|
||||
stroke: colours.$attribute-die-border-color;
|
||||
}
|
||||
|
||||
.topright {
|
||||
fill: color.adjust(colours.$attribute-die-color, $lightness: numbers.$darken_factor);
|
||||
stroke: colours.$attribute-die-border-color;
|
||||
}
|
||||
|
||||
.bottomright, .bottom {
|
||||
fill: color.adjust(colours.$attribute-die-color, $lightness: numbers.$darkest_factor);
|
||||
stroke: colours.$attribute-die-border-color;
|
||||
}
|
||||
}
|
||||
|
||||
.wert {
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 48px;
|
||||
top: 0;
|
||||
line-height: 48px;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
color: colours.$attribute-die-label-color;
|
||||
}
|
||||
|
||||
.name {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
line-height: 12px;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
color: colours.$attribute-label-color;
|
||||
background-color: colours.$attribute-label-background-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,651 +0,0 @@
|
|||
@use "sass:color";
|
||||
@use "_numbers";
|
||||
@use "_colours" as colour;
|
||||
|
||||
|
||||
.dsa41.sheet.actor.character {
|
||||
|
||||
.window-header.flexrow.draggable.resizable {
|
||||
}
|
||||
|
||||
$sidebar-width: 224px;
|
||||
$attribute-height: 60px;
|
||||
$tabs-spacing: 14px;
|
||||
$tabs-height: 26px;
|
||||
|
||||
.window-content {
|
||||
display: unset; /* we are on our own */
|
||||
position: relative;
|
||||
|
||||
header.sheet-header {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: $attribute-height;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
div.head-data {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: $attribute-height;
|
||||
width: $sidebar-width;
|
||||
bottom: 0;
|
||||
padding: 8px;
|
||||
|
||||
|
||||
.profile-img {
|
||||
width: $sidebar-width - 16px;
|
||||
}
|
||||
}
|
||||
|
||||
nav.sheet-tabs.tabs {
|
||||
position: absolute;
|
||||
left: $sidebar-width;
|
||||
top: $attribute-height+$tabs-spacing;
|
||||
right: 0;
|
||||
height: $tabs-height;
|
||||
}
|
||||
|
||||
section.sheet-body {
|
||||
position: absolute;
|
||||
top: $attribute-height+$tabs-height+$tabs-spacing+4px;
|
||||
left: $sidebar-width;
|
||||
right: 4px;
|
||||
bottom: 4px;
|
||||
padding: 8px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.tab.overview.active {
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
.meta-data {
|
||||
flex: 0;
|
||||
|
||||
columns: 2;
|
||||
gap: 0 16px;
|
||||
|
||||
|
||||
div {
|
||||
break-inside: avoid;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.double {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-areas: 'label label' 'left right';
|
||||
gap: 0 8px;
|
||||
|
||||
label {
|
||||
grid-area: label;
|
||||
}
|
||||
}
|
||||
|
||||
.editor {
|
||||
background-color: rgba(0, 0, 0, 0.2)
|
||||
}
|
||||
|
||||
& + .meta-data {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.meta-data.html {
|
||||
|
||||
& > div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
label {
|
||||
flex: 0;
|
||||
}
|
||||
|
||||
.editor {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.tab.attributes.active {
|
||||
height: 100%;
|
||||
|
||||
.attribute {
|
||||
padding: 8px 0;
|
||||
display: flex;
|
||||
gap: 0 8px;
|
||||
|
||||
label {
|
||||
width: 120px;
|
||||
text-align: right;
|
||||
vertical-align: middle;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
input {
|
||||
max-width: 80px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.mod {
|
||||
color: grey;
|
||||
text-shadow: 0 -1px 0 #ccc;
|
||||
box-Shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
|
||||
border-radius: 4px;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
background: linear-gradient(0deg, rgba(24, 24, 24, 1) 0%, rgba(80, 80, 80, 1) 100%);;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
line-height: 24px;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.attributes-overview {
|
||||
|
||||
columns: 2;
|
||||
gap: 0 16px;
|
||||
|
||||
}
|
||||
|
||||
.resource-overview {
|
||||
|
||||
.attribute {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.advantages, .special-abilities {
|
||||
margin-bottom: 16px;
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
text-indent: 0;
|
||||
|
||||
li {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.advantage, .special-ability {
|
||||
position: relative;
|
||||
border: 1px solid gold;
|
||||
box-shadow: 2px 2px 4px #000;
|
||||
border-radius: 8px;
|
||||
height: 24px;
|
||||
color: gold;
|
||||
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.2);
|
||||
display: inline-block;
|
||||
padding: 0 8px;
|
||||
margin-left: 0;
|
||||
margin-bottom: 4px;
|
||||
background-image: url("../assets/velvet_button.png");
|
||||
background-repeat: repeat-y;
|
||||
background-size: cover;
|
||||
|
||||
span {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
line-height: 24px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
&.special-ability {
|
||||
&::after {
|
||||
background: rgba(128, 0, 96, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-radius: 8px;
|
||||
background: rgba(0, 128, 0, 0.5);
|
||||
}
|
||||
|
||||
& + .advantage, & + .special-ability {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
&.disadvantage {
|
||||
font-style: italic;
|
||||
|
||||
&::after {
|
||||
background: rgba(128, 0, 0, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
.backpack.active {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 320px;
|
||||
grid-template-rows: 74px 1fr;
|
||||
gap: 10px;
|
||||
height: 100%;
|
||||
grid-template-areas:
|
||||
"capacity capacity"
|
||||
"inventory equipment";
|
||||
|
||||
.capacity {
|
||||
|
||||
grid-area: capacity;
|
||||
|
||||
.resource {
|
||||
|
||||
position: relative;
|
||||
border: 1px inset #ccc;
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
height: 8px;
|
||||
|
||||
span.fill {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background: linear-gradient(to bottom, #0bad29 0%, #11f128 50%, #0cde24 51%, #6ff77b 100%);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.inventory {
|
||||
grid-area: inventory;
|
||||
|
||||
.equipment:hover {
|
||||
.item-name {
|
||||
text-shadow: 0 0 10px rgb(255 0 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.tab.combat.active {
|
||||
|
||||
display: grid;
|
||||
|
||||
grid-template-columns: 1fr 320px;
|
||||
grid-template-rows: 32px 32px 1fr;
|
||||
grid-template-areas: "res res" "wounds wounds" "actions actions";
|
||||
gap: 10px;
|
||||
|
||||
.tab-resources {
|
||||
grid-area: res;
|
||||
}
|
||||
|
||||
.wounds {
|
||||
position: relative;
|
||||
height: 24px;
|
||||
display: flex;
|
||||
margin-bottom: 8px;
|
||||
padding-left: 130px;
|
||||
grid-area: wounds;
|
||||
|
||||
label {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
line-height: 24px;
|
||||
width: 120px;
|
||||
bottom: 0;
|
||||
vertical-align: middle;
|
||||
text-align: right;
|
||||
height: 24px;
|
||||
display: inline-block;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.filled-segment {
|
||||
border: 1px solid black;
|
||||
background-image: url('../assets/gradient.png');
|
||||
background-size: 24px 100%;
|
||||
position: relative;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
line-height: 24px;
|
||||
color: white;
|
||||
text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.3);
|
||||
background-color: rgba(255, 0, 0, 0.8);
|
||||
background-blend-mode: multiply;
|
||||
|
||||
}
|
||||
|
||||
.empty-segment {
|
||||
border: 1px solid black;
|
||||
background-image: url('../assets/gradient.png');
|
||||
background-size: 32px 100%;
|
||||
position: relative;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
line-height: 24px;
|
||||
color: gold;
|
||||
text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.3);
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
background-blend-mode: multiply;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.actions {
|
||||
grid-area: actions;
|
||||
}
|
||||
|
||||
&.zones {
|
||||
grid-template-areas: "res res" "wounds wounds" "actions paperdoll";
|
||||
|
||||
.paperdoll {
|
||||
grid-area: paperdoll;
|
||||
|
||||
div {
|
||||
position: relative;
|
||||
margin-left: 9px;
|
||||
margin-top: 42px;
|
||||
|
||||
.wound {
|
||||
position: absolute;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 16px;
|
||||
border: 1px solid black;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3);
|
||||
line-height: 32px;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
color: red;
|
||||
|
||||
|
||||
&.armlinks {
|
||||
top: 146px;
|
||||
left: 210px;
|
||||
}
|
||||
|
||||
&.armrechts {
|
||||
top: 146px;
|
||||
left: 60px;
|
||||
}
|
||||
|
||||
&.beinlinks {
|
||||
top: 346px;
|
||||
left: 210px;
|
||||
}
|
||||
|
||||
&.beinrechts {
|
||||
top: 346px;
|
||||
left: 60px;
|
||||
}
|
||||
|
||||
&.bauch {
|
||||
top: 166px;
|
||||
left: 136px;
|
||||
}
|
||||
|
||||
&.kopf {
|
||||
top: 6px;
|
||||
left: 136px
|
||||
}
|
||||
|
||||
&.brust {
|
||||
top: 86px;
|
||||
left: 110px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.armor {
|
||||
position: absolute;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 0 0 16px 16px;
|
||||
line-height: 32px;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
border: 1px solid silver;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3);
|
||||
color: silver;
|
||||
|
||||
&.armlinks {
|
||||
top: 180px;
|
||||
left: 210px;
|
||||
}
|
||||
|
||||
&.armrechts {
|
||||
top: 180px;
|
||||
left: 60px;
|
||||
}
|
||||
|
||||
&.beinlinks {
|
||||
top: 380px;
|
||||
left: 210px;
|
||||
}
|
||||
|
||||
&.beinrechts {
|
||||
top: 380px;
|
||||
left: 60px;
|
||||
}
|
||||
|
||||
&.bauch {
|
||||
top: 200px;
|
||||
left: 136px;
|
||||
}
|
||||
|
||||
&.kopf {
|
||||
top: 40px;
|
||||
left: 136px
|
||||
}
|
||||
|
||||
&.brust {
|
||||
top: 120px;
|
||||
left: 110px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
.tab.spells {
|
||||
|
||||
tr {
|
||||
height: 24px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
td {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
$color: #05f;
|
||||
|
||||
.spell.rollable svg {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
top: 1px;
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
|
||||
.border {
|
||||
fill: #0000;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
|
||||
.die-column {
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
.clickable {
|
||||
span {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
tbody {
|
||||
|
||||
tr {
|
||||
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
background-image: linear-gradient(to right, rgba(color.scale($color, $lightness: numbers.$zebra_light), numbers.$start_gradient), rgba(color.scale($color, $lightness: numbers.$zebra_light), numbers.$end_2_gradient));
|
||||
border-top-right-radius: 8px;
|
||||
border-bottom-right-radius: 8px;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 12px;
|
||||
bottom: 2px;
|
||||
right: 33%;
|
||||
z-index: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&:nth-child(odd) {
|
||||
&::after {
|
||||
background-image: linear-gradient(to right, rgba(color.scale($color, $lightness: numbers.$zebra_dark), numbers.$start_gradient), rgba(color.scale($color, $lightness: numbers.$zebra_dark), numbers.$end_2_gradient));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.merkmal-list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
text-indent: 0;
|
||||
|
||||
li {
|
||||
display: inline-block;
|
||||
padding: 0 4px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.tab.liturgies {
|
||||
|
||||
table {
|
||||
border-top: unset;
|
||||
border-bottom: unset;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.liturgy-header {
|
||||
background: unset;
|
||||
border: unset;
|
||||
|
||||
tr {
|
||||
height: 90px;
|
||||
|
||||
th {
|
||||
vertical-align: middle;
|
||||
color: black;
|
||||
text-shadow: 2px 2px 1px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
td, th {
|
||||
padding-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.tab-resources {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 0 16px;
|
||||
padding-bottom: 8px;
|
||||
|
||||
& > div {
|
||||
|
||||
|
||||
height: 32px;
|
||||
position: relative;
|
||||
|
||||
label {
|
||||
width: 80px;
|
||||
line-height: 32px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
input {
|
||||
display: inline-block;
|
||||
width: 40px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
span.inline {
|
||||
line-height: 32px;
|
||||
vertical-align: middle;
|
||||
width: 40px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,174 +0,0 @@
|
|||
@use "_colours" as colour;
|
||||
@use 'sass:color';
|
||||
@use "_numbers";
|
||||
|
||||
.dsa41.sheet.actor.creature {
|
||||
|
||||
.window-content {
|
||||
|
||||
form {
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 74px 30px 1fr;
|
||||
|
||||
.sheet-header {
|
||||
|
||||
height: 64px;
|
||||
display: grid;
|
||||
grid-template-columns: 64px max-content;
|
||||
grid-template-rows: 1fr;
|
||||
gap: 0 8px;
|
||||
|
||||
img {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
input {
|
||||
line-height: 64px;
|
||||
height: 64px;
|
||||
font-size: 2rem;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.sheet-body {
|
||||
.tab {
|
||||
margin: 8px;
|
||||
|
||||
height: 100%;
|
||||
|
||||
div.input {
|
||||
|
||||
height: 32px;
|
||||
display: grid;
|
||||
grid-template-columns: 120px 1fr;
|
||||
|
||||
&.compound {
|
||||
|
||||
grid-template-columns: 120px 140px 1fr;
|
||||
|
||||
span {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
|
||||
input {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
label {
|
||||
height: 32px;
|
||||
width: 100%;
|
||||
|
||||
span {
|
||||
width: 120px;
|
||||
text-align: left;
|
||||
line-height: 32px;
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
input {
|
||||
text-align: right;
|
||||
line-height: 32px;
|
||||
vertical-align: middle;
|
||||
padding-left: 120px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
table.attacks-table {
|
||||
|
||||
td {
|
||||
padding: 2px 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.rollable.tablecell {
|
||||
position: relative;
|
||||
|
||||
|
||||
.attacks-die {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
position: absolute;
|
||||
left: 4px;
|
||||
top: 4px;
|
||||
bottom: 2px;
|
||||
z-index: 1;
|
||||
|
||||
|
||||
svg {
|
||||
stroke-width: 0.5;
|
||||
|
||||
$color: #f30;
|
||||
|
||||
.border {
|
||||
fill: #0000;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
input {
|
||||
position: absolute;
|
||||
left: 16px;
|
||||
top: 4px;
|
||||
bottom: 2px;
|
||||
right: 4px;
|
||||
width: unset;
|
||||
text-indent: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.button-inline {
|
||||
border: unset;
|
||||
background: unset;
|
||||
}
|
||||
|
||||
.editor {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
|
||||
.dsa41.sheet.actor.character {
|
||||
.tab.skills {
|
||||
|
||||
columns: 2;
|
||||
column-gap: 20px;
|
||||
|
||||
.talent-group {
|
||||
break-inside: avoid-column;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,247 +0,0 @@
|
|||
@use "sass:map";
|
||||
@use "sass:color";
|
||||
@use "colours" as colour;
|
||||
@use "numbers";
|
||||
|
||||
$deity_colours_border: (
|
||||
"Praios": orange,
|
||||
"Rondra": red,
|
||||
"Efferd": #74d0ec,
|
||||
"Travia": #c6491a,
|
||||
"Boron": #515151,
|
||||
"Hesinde": #089e08,
|
||||
"Firun": #8fdeff,
|
||||
"Tsa": #6a24d8,
|
||||
"Phex": #1569da,
|
||||
"Peraine": #56a116,
|
||||
"Ingerimm": #a53d19,
|
||||
"Rahja": #ed70c2,
|
||||
);
|
||||
$deity_colours_tint: (
|
||||
"Praios": rgba(orange, 0.5),
|
||||
"Rondra": rgba(red, 0.5),
|
||||
"Efferd": rgba(#74d0ec, 0.5),
|
||||
"Travia": rgba(#c6491a, 0.5),
|
||||
"Boron": rgba(#515151, 0.5),
|
||||
"Hesinde": rgba(#089e08, 0.5),
|
||||
"Firun": rgba(#8fdeff, 0.5),
|
||||
"Tsa": linear-gradient(
|
||||
-45deg,
|
||||
rgba(255, 0, 0, 0.5) 0%,
|
||||
rgba(255, 154, 0, 0.5) 10%,
|
||||
rgba(208, 222, 33, 0.5) 20%,
|
||||
rgba(79, 220, 74, 0.5) 30%,
|
||||
rgba(63, 218, 216, 0.5) 40%,
|
||||
rgba(47, 201, 226, 0.5) 50%,
|
||||
rgba(28, 127, 238, 0.5) 60%,
|
||||
rgba(95, 21, 242, 0.5) 70%,
|
||||
rgba(186, 12, 248, 0.5) 80%,
|
||||
rgba(251, 7, 217, 0.5) 90%,
|
||||
rgba(255, 0, 0, 0.5) 100%
|
||||
),
|
||||
"Phex": rgba(#1569da, 0.5),
|
||||
"Peraine": rgba(#56a116, 0.5),
|
||||
"Ingerimm": rgba(#a53d19, 0.5),
|
||||
"Rahja": rgba(#ed70c2, 0.5),
|
||||
);
|
||||
|
||||
@mixin coloring($name) {
|
||||
$color: map.get($deity_colours_border, $name);
|
||||
$color-tint: map.get($deity_colours_tint, $name);
|
||||
&.#{$name} {
|
||||
|
||||
th.background {
|
||||
&::after {
|
||||
background: $color-tint;
|
||||
}
|
||||
}
|
||||
|
||||
.banner-bot {
|
||||
border-color: $color;
|
||||
}
|
||||
|
||||
.banner-mid {
|
||||
border-color: $color;
|
||||
}
|
||||
|
||||
.banner-top {
|
||||
&::before, &::after {
|
||||
border-color: $color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tab.liturgies {
|
||||
table {
|
||||
|
||||
@include coloring('Praios');
|
||||
@include coloring('Rondra');
|
||||
@include coloring('Efferd');
|
||||
@include coloring('Travia');
|
||||
@include coloring('Boron');
|
||||
@include coloring('Hesinde');
|
||||
@include coloring('Firun');
|
||||
@include coloring('Tsa');
|
||||
@include coloring('Phex');
|
||||
@include coloring('Peraine');
|
||||
@include coloring('Ingerimm');
|
||||
@include coloring('Rahja');
|
||||
|
||||
tr {
|
||||
th.background {
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
content: '';
|
||||
background-image: url("../assets/velvet_strip.png");
|
||||
background-repeat: repeat-y;
|
||||
background-size: cover;
|
||||
width: 86px;
|
||||
height: 100%;
|
||||
|
||||
top: 45px;
|
||||
left: 12px;
|
||||
}
|
||||
|
||||
&::after { /* for tinting the texture */
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 86px;
|
||||
height: 100%;
|
||||
|
||||
top: 45px;
|
||||
left: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.banner-top {
|
||||
position: relative;
|
||||
|
||||
width: 90px;
|
||||
|
||||
img {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 1px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
border: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&::after {
|
||||
z-index: 0;
|
||||
border-width: 0 4px 0 4px;
|
||||
//background-color: #64b;
|
||||
border-style: solid;
|
||||
position: absolute;
|
||||
content: "";
|
||||
left: -2px;
|
||||
top: 45px;
|
||||
bottom: 0;
|
||||
width: 94px;
|
||||
}
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
border-radius: 45px;
|
||||
height: 94px;
|
||||
width: 94px;
|
||||
content: '';
|
||||
left: -2px;
|
||||
right: -2px;
|
||||
top: 0;
|
||||
border-width: 4px;
|
||||
border-style: solid;
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
|
||||
.banner-mid {
|
||||
position: relative;
|
||||
border-width: 0 4px 0 4px;
|
||||
//background-color: #64b;
|
||||
border-style: solid;
|
||||
width: 90px;
|
||||
|
||||
div {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
div.rank-label {
|
||||
position: absolute;
|
||||
left: 2px;
|
||||
right: 2px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
border-bottom: 2px solid black;
|
||||
color: gold;
|
||||
text-shadow: 2px 2px 1px black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.banner-bot {
|
||||
position: relative;
|
||||
border-width: 4px;
|
||||
border-style: solid;
|
||||
width: 90px;
|
||||
height: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.liturgy.rollable {
|
||||
width: 24px;
|
||||
|
||||
svg {
|
||||
$color: #e4de61;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
top: 1px;
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
|
||||
.border {
|
||||
fill: #0000;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.clickable:hover {
|
||||
text-shadow: 0 0 10px rgb(255 0 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
@use "./_colours";
|
||||
@use "./_numbers";
|
||||
@use "sass:color";
|
||||
|
||||
.player-action {
|
||||
|
||||
display: inline-block;
|
||||
width: 120px;
|
||||
height: 80px;
|
||||
float: left;
|
||||
margin: 0 8px 8px 0;
|
||||
|
||||
border: 1px solid #333;
|
||||
background-color: color.scale(colours.$default-action, $alpha: 20%);
|
||||
color: colours.$default-action-color;
|
||||
border-radius: 4px;
|
||||
box-shadow: numbers.$pill-box-inset numbers.$pill-box-inset numbers.$pill-box-blur-radius colours.$pill-box-shadow;
|
||||
|
||||
|
||||
&.special-ability {
|
||||
background-color: color.scale(colours.$special-action, $alpha: 20%);
|
||||
color: colours.$special-action-color;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
@use "./numbers";
|
||||
@use "./colours";
|
||||
@use "./assets";
|
||||
|
||||
.dsa41.sheet {
|
||||
|
||||
nav.sheet-tabs.tabs {
|
||||
|
||||
position: relative;
|
||||
display: flow;
|
||||
border-top: unset;
|
||||
border-bottom: unset;
|
||||
margin-bottom: 9px;
|
||||
|
||||
a.item[data-tab] {
|
||||
|
||||
background-color: colours.$tab-inactive-background-color;
|
||||
|
||||
&.active {
|
||||
border-left: numbers.$tab-border-width solid colours.$tab-border-color;
|
||||
border-top: numbers.$tab-border-width solid colours.$tab-border-color;
|
||||
border-right: numbers.$tab-border-width solid colours.$tab-border-color;
|
||||
border-bottom: 0;
|
||||
top: numbers.$tab-border-width*2;
|
||||
background: assets.$tab-background;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
section.sheet-body {
|
||||
|
||||
border: numbers.$tab-border-width solid colours.$tab-border-color;
|
||||
background: assets.$tab-pane-background;
|
||||
|
||||
div.tab {
|
||||
|
||||
overflow: auto;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -34,9 +34,35 @@ $tab-background-color: #fff8;
|
|||
$dice-box-shadow: rgba(0, 0, 0, 0.25);
|
||||
$pill-box-shadow: rgba(0, 0, 0, 0.3);
|
||||
|
||||
$tab-shadow: rgba(0, 0, 0, 0.3);
|
||||
$tab-pane-shadow: rgba(0, 0, 0, 0.3);
|
||||
|
||||
$attribute-die-border-color: #000;
|
||||
|
||||
$attribute-die-color: #F00;
|
||||
$attribute-die-label-color: #FFF;
|
||||
|
||||
$attribute-die-co-color: #b3241a;
|
||||
$attribute-die-sm-color: #8259a3;
|
||||
$attribute-die-in-color: #388834;
|
||||
$attribute-die-ch-color: #0d0d0d;
|
||||
|
||||
$attribute-die-dx-color: #688ec4;
|
||||
$attribute-die-ag-color: #d5b467;
|
||||
$attribute-die-bd-color: #a3a3a3;
|
||||
$attribute-die-st-color: #d6a878;
|
||||
|
||||
$attribute-die-co-text-color: #fff;
|
||||
$attribute-die-sm-text-color: #fff;
|
||||
$attribute-die-in-text-color: #fff;
|
||||
$attribute-die-ch-text-color: #fff;
|
||||
|
||||
$attribute-die-dx-text-color: #000;
|
||||
$attribute-die-ag-text-color: #000;
|
||||
$attribute-die-bd-text-color: #000;
|
||||
$attribute-die-st-text-color: #000;
|
||||
|
||||
|
||||
$attribute-label-color: #FFF;
|
||||
$attribute-label-background-color: #0008;
|
||||
|
||||
|
|
@ -44,9 +70,9 @@ $rollable-die-border-color: #000;
|
|||
|
||||
$dice-box-border-color: #333;
|
||||
|
||||
$default-action: #c41;
|
||||
$default-action-color: #FFF;
|
||||
$default-action: rgba(204, 68, 17, 0.8);
|
||||
$default-action-color: #000;
|
||||
|
||||
$special-action: #42c;
|
||||
$special-action: rgba(68, 34, 204, 0.8);
|
||||
|
||||
$special-action-color: #FFF;
|
||||
$special-action-color: #000;
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
@font-face {
|
||||
font-family: "Andalus";
|
||||
src: url("/systems/DSA_4-1/assets/fonts/andlso.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Gentium";
|
||||
src: url("/systems/DSA_4-1/assets/fonts/GenBasR.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Gentium";
|
||||
src: url("/systems/DSA_4-1/assets/fonts/GenBasI.ttf");
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Gentium";
|
||||
src: url("/systems/DSA_4-1/assets/fonts/GenBasB.ttf");
|
||||
font-weight: bold;
|
||||
}
|
||||
|
|
@ -16,6 +16,14 @@ $dice-box-inset: 4px;
|
|||
$dice-box-blur-radius: 4px;
|
||||
$dice-box-border-width: 1px;
|
||||
|
||||
$tab-shadow-right: 1px;
|
||||
$tab-shadow-bottom: 0;
|
||||
$tab-shadow-blur-radius: 0;
|
||||
|
||||
$tab-pane-shadow-right: 1px;
|
||||
$tab-pane-shadow-bottom: 1px;
|
||||
$tab-pane-shadow-blur-radius: 0;
|
||||
|
||||
$pill-box-inset: 2px;
|
||||
$pill-box-blur-radius: 4px;
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
svg {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
.application.sheet.dsa41 {
|
||||
|
||||
--font-body: Gentium, sans-serif;
|
||||
|
||||
label,
|
||||
.sheet-tabs.tabs a,
|
||||
h2, h3 {
|
||||
font-family: Gentium, sans-serif;
|
||||
font-weight: bold;
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
h2 {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
ul {
|
||||
li {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
input,
|
||||
.rkp .pill {
|
||||
font-family: Andalus, sans-serif;
|
||||
}
|
||||
|
||||
.editor.prosemirror.active, .editor.prosemirror.inactive {
|
||||
font-family: Gentium, sans-serif;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
@use "../atoms/colours";
|
||||
@use "../atoms/numbers";
|
||||
@use "../atoms/assets";
|
||||
@use "sass:color";
|
||||
|
||||
.dsa41.sheet.actor.character {
|
||||
|
||||
.sheet-header {
|
||||
position: relative;
|
||||
|
||||
.attributes {
|
||||
display: flex;
|
||||
|
||||
.attribute.rollable {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
position: relative;
|
||||
box-shadow: inset numbers.$dice-box-inset numbers.$dice-box-inset numbers.$dice-box-blur-radius colours.$dice-box-shadow;
|
||||
background: assets.$dice-box-background;
|
||||
margin-left: 2px;
|
||||
border: numbers.$dice-box-border-width inset colours.$dice-box-border-color;
|
||||
|
||||
.die {
|
||||
stroke-width: 0.5;
|
||||
|
||||
svg {
|
||||
position: absolute;
|
||||
left: -6px;
|
||||
top: -6px;
|
||||
bottom: -6px;
|
||||
right: -6px;
|
||||
|
||||
path {
|
||||
fill: colours.$attribute-die-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wert {
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
left: -2px;
|
||||
width: 48px;
|
||||
top: -2px;
|
||||
font-size: smaller;
|
||||
line-height: 48px;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
color: colours.$attribute-die-label-color;
|
||||
}
|
||||
|
||||
.name {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
line-height: 12px;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
color: colours.$attribute-label-color;
|
||||
background-color: colours.$attribute-label-background-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.colorfulDice {
|
||||
|
||||
&.Mut {
|
||||
|
||||
.die svg path {
|
||||
fill: colours.$attribute-die-co-color;
|
||||
}
|
||||
|
||||
.wert {
|
||||
color: colours.$attribute-die-co-text-color;
|
||||
}
|
||||
}
|
||||
|
||||
.Klugheit {
|
||||
|
||||
.die svg path {
|
||||
fill: colours.$attribute-die-sm-color;
|
||||
}
|
||||
|
||||
.wert {
|
||||
color: colours.$attribute-die-sm-text-color;
|
||||
}
|
||||
}
|
||||
|
||||
.Intuition {
|
||||
|
||||
.die svg path {
|
||||
fill: colours.$attribute-die-in-color;
|
||||
}
|
||||
|
||||
.wert {
|
||||
color: colours.$attribute-die-in-text-color;
|
||||
}
|
||||
}
|
||||
|
||||
.Charisma {
|
||||
|
||||
.die svg path {
|
||||
fill: colours.$attribute-die-ch-color;
|
||||
}
|
||||
|
||||
.wert {
|
||||
color: colours.$attribute-die-ch-text-color;
|
||||
}
|
||||
}
|
||||
|
||||
.Geschicklichkeit {
|
||||
|
||||
.die svg path {
|
||||
fill: colours.$attribute-die-dx-color;
|
||||
}
|
||||
|
||||
.wert {
|
||||
color: colours.$attribute-die-dx-text-color;
|
||||
}
|
||||
}
|
||||
|
||||
.Fingerfertigkeit {
|
||||
|
||||
.die svg path {
|
||||
fill: colours.$attribute-die-ag-color;
|
||||
}
|
||||
|
||||
.wert {
|
||||
color: colours.$attribute-die-ag-text-color;
|
||||
}
|
||||
}
|
||||
|
||||
.Konstitution {
|
||||
|
||||
.die svg path {
|
||||
fill: colours.$attribute-die-bd-color;
|
||||
}
|
||||
|
||||
.wert {
|
||||
color: colours.$attribute-die-bd-text-color;
|
||||
}
|
||||
}
|
||||
|
||||
.Körperkraft {
|
||||
|
||||
.die svg path {
|
||||
fill: colours.$attribute-die-st-color;
|
||||
}
|
||||
|
||||
.wert {
|
||||
color: colours.$attribute-die-st-text-color;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
.droppable {
|
||||
|
||||
.inventory-table {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.inventory-table::after {
|
||||
|
||||
content: 'Gegenstände hier fallen lassen';
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
border-radius: 8px;
|
||||
border-style: dashed;
|
||||
border-color: gray;
|
||||
line-height: 34px;
|
||||
height: 34px;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
color: gray;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
.dsa41.sheet.actor.character {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,251 @@
|
|||
@use "sass:map";
|
||||
@use "sass:color";
|
||||
@use "../atoms/colours" as colour;
|
||||
@use "../atoms/numbers";
|
||||
|
||||
$deity_colours_border: (
|
||||
"Praios": orange,
|
||||
"Rondra": red,
|
||||
"Efferd": #74d0ec,
|
||||
"Travia": #c6491a,
|
||||
"Boron": #515151,
|
||||
"Hesinde": #089e08,
|
||||
"Firun": #8fdeff,
|
||||
"Tsa": #6a24d8,
|
||||
"Phex": #1569da,
|
||||
"Peraine": #56a116,
|
||||
"Ingerimm": #a53d19,
|
||||
"Rahja": #ed70c2,
|
||||
);
|
||||
$deity_colours_tint: (
|
||||
"Praios": rgba(orange, 0.5),
|
||||
"Rondra": rgba(red, 0.5),
|
||||
"Efferd": rgba(#74d0ec, 0.5),
|
||||
"Travia": rgba(#c6491a, 0.5),
|
||||
"Boron": rgba(#515151, 0.5),
|
||||
"Hesinde": rgba(#089e08, 0.5),
|
||||
"Firun": rgba(#8fdeff, 0.5),
|
||||
"Tsa": linear-gradient(
|
||||
-45deg,
|
||||
rgba(255, 0, 0, 0.5) 0%,
|
||||
rgba(255, 154, 0, 0.5) 10%,
|
||||
rgba(208, 222, 33, 0.5) 20%,
|
||||
rgba(79, 220, 74, 0.5) 30%,
|
||||
rgba(63, 218, 216, 0.5) 40%,
|
||||
rgba(47, 201, 226, 0.5) 50%,
|
||||
rgba(28, 127, 238, 0.5) 60%,
|
||||
rgba(95, 21, 242, 0.5) 70%,
|
||||
rgba(186, 12, 248, 0.5) 80%,
|
||||
rgba(251, 7, 217, 0.5) 90%,
|
||||
rgba(255, 0, 0, 0.5) 100%
|
||||
),
|
||||
"Phex": rgba(#1569da, 0.5),
|
||||
"Peraine": rgba(#56a116, 0.5),
|
||||
"Ingerimm": rgba(#a53d19, 0.5),
|
||||
"Rahja": rgba(#ed70c2, 0.5),
|
||||
);
|
||||
|
||||
@mixin coloring($name) {
|
||||
$color: map.get($deity_colours_border, $name);
|
||||
$color-tint: map.get($deity_colours_tint, $name);
|
||||
&.#{$name} {
|
||||
|
||||
th.background {
|
||||
&::after {
|
||||
background: $color-tint;
|
||||
}
|
||||
}
|
||||
|
||||
.banner-bot {
|
||||
border-color: $color;
|
||||
}
|
||||
|
||||
.banner-mid {
|
||||
border-color: $color;
|
||||
}
|
||||
|
||||
.banner-top {
|
||||
&::before, &::after {
|
||||
border-color: $color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dsa41.sheet {
|
||||
|
||||
.tab.liturgies {
|
||||
table {
|
||||
|
||||
@include coloring('Praios');
|
||||
@include coloring('Rondra');
|
||||
@include coloring('Efferd');
|
||||
@include coloring('Travia');
|
||||
@include coloring('Boron');
|
||||
@include coloring('Hesinde');
|
||||
@include coloring('Firun');
|
||||
@include coloring('Tsa');
|
||||
@include coloring('Phex');
|
||||
@include coloring('Peraine');
|
||||
@include coloring('Ingerimm');
|
||||
@include coloring('Rahja');
|
||||
|
||||
tr {
|
||||
th.background {
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
content: '';
|
||||
background-image: url("/systems/DSA_4-1/assets/velvet_strip.png");
|
||||
background-repeat: repeat-y;
|
||||
background-size: cover;
|
||||
width: 86px;
|
||||
height: 100%;
|
||||
|
||||
top: 45px;
|
||||
left: 28px;
|
||||
}
|
||||
|
||||
&::after { /* for tinting the texture */
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 86px;
|
||||
height: 100%;
|
||||
|
||||
top: 45px;
|
||||
left: 28px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.banner-top {
|
||||
position: relative;
|
||||
|
||||
width: 90px;
|
||||
|
||||
img {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 1px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
border: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&::after {
|
||||
z-index: 0;
|
||||
border-width: 0 4px 0 4px;
|
||||
//background-color: #64b;
|
||||
border-style: solid;
|
||||
position: absolute;
|
||||
content: "";
|
||||
left: -2px;
|
||||
top: 45px;
|
||||
bottom: 0;
|
||||
width: 94px;
|
||||
}
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
border-radius: 45px;
|
||||
height: 94px;
|
||||
width: 94px;
|
||||
content: '';
|
||||
left: -2px;
|
||||
right: -2px;
|
||||
top: 0;
|
||||
border-width: 4px;
|
||||
border-style: solid;
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
|
||||
.banner-mid {
|
||||
position: relative;
|
||||
border-width: 0 4px 0 4px;
|
||||
//background-color: #64b;
|
||||
border-style: solid;
|
||||
width: 90px;
|
||||
|
||||
div {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
div.rank-label {
|
||||
position: absolute;
|
||||
left: 2px;
|
||||
right: 2px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
border-bottom: 2px solid black;
|
||||
color: gold;
|
||||
text-shadow: 2px 2px 1px black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.banner-bot {
|
||||
position: relative;
|
||||
border-width: 4px;
|
||||
border-style: solid;
|
||||
width: 90px;
|
||||
height: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.liturgy.rollable {
|
||||
width: 24px;
|
||||
|
||||
svg {
|
||||
$color: #e4de61;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
top: 1px;
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
|
||||
.border {
|
||||
fill: #0000;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.clickable:hover {
|
||||
text-shadow: 0 0 10px rgb(255 0 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
.application.sheet.dsa41 {
|
||||
|
||||
.pill {
|
||||
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
font-size: 14px;
|
||||
vertical-align: middle;
|
||||
padding: 1px 4px;
|
||||
margin-right: 4px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid orange;
|
||||
color: orange;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5), inset -1px -1px 0 rgba(0, 0, 0, 0.1);
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
@use "../atoms/colours";
|
||||
@use "../atoms/numbers";
|
||||
@use "sass:color";
|
||||
|
||||
.dsa41.sheet {
|
||||
.player-action {
|
||||
|
||||
display: inline-block;
|
||||
width: 120px;
|
||||
height: 80px;
|
||||
float: left;
|
||||
margin: 0 8px 8px 0;
|
||||
position: relative;
|
||||
|
||||
border: 1px solid #333;
|
||||
color: colours.$default-action-color;
|
||||
background: url('../../../ui/parchment.jpg');
|
||||
background-size: 128px 100%;
|
||||
border-radius: 4px;
|
||||
box-shadow: numbers.$pill-box-inset numbers.$pill-box-inset numbers.$pill-box-blur-radius colours.$pill-box-shadow;
|
||||
|
||||
span {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
&::after { /* for tinting the texture */
|
||||
content: "";
|
||||
position: absolute;
|
||||
background-color: colours.$default-action;
|
||||
background-blend-mode: multiply;
|
||||
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&.special-ability::after {
|
||||
background-color: colours.$special-action;
|
||||
color: colours.$special-action-color;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
.application.sheet.dsa41 {
|
||||
|
||||
.editor.prosemirror {
|
||||
flex: 1;
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.1);
|
||||
border: 1px solid #666;
|
||||
outline: 1px solid transparent;
|
||||
border-radius: 4px;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
@use 'sass:color';
|
||||
@use 'sass:map';
|
||||
@use "_colours" as colour;
|
||||
@use "_numbers" as numbers;
|
||||
@use "../atoms/colours" as colour;
|
||||
@use "../atoms/numbers" as numbers;
|
||||
|
||||
$rollable_colours: (
|
||||
"nachteil": colour.$nachteil-color,
|
||||
|
|
@ -146,9 +146,8 @@ $rollable_colours_font: (
|
|||
.value {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
left: 0;
|
||||
left: -1px;
|
||||
top: -2px;
|
||||
scale: 0.8;
|
||||
|
||||
img {
|
||||
position: absolute;
|
||||
|
|
@ -171,39 +170,22 @@ $rollable_colours_font: (
|
|||
.die {
|
||||
stroke-width: 0.5;
|
||||
|
||||
svg {
|
||||
|
||||
margin: -4px;
|
||||
|
||||
path {
|
||||
fill: $color;
|
||||
stroke: colour.$rollable-die-border-color;
|
||||
stroke-width: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
span.value {
|
||||
color: $font_color;
|
||||
|
||||
}
|
||||
|
||||
.border {
|
||||
fill: colour.$rollable-die-border-color;
|
||||
stroke: colour.$rollable-die-border-color;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
|
|
@ -60,7 +60,7 @@
|
|||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background: url('../assets/gradient.png');
|
||||
background: url('/systems/DSA_4-1/assets/gradient.png');
|
||||
background-size: 32px 100%;
|
||||
|
||||
&::after {
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
@use "../atoms/numbers";
|
||||
@use "../atoms/colours";
|
||||
@use "../atoms/assets";
|
||||
|
||||
.dsa41.sheet {
|
||||
|
||||
nav.sheet-tabs.tabs {
|
||||
|
||||
position: relative;
|
||||
display: flow;
|
||||
border-top: unset;
|
||||
border-bottom: unset;
|
||||
margin-bottom: 0;
|
||||
|
||||
a.item[data-tab] {
|
||||
|
||||
background-color: colours.$tab-inactive-background-color;
|
||||
|
||||
&.active {
|
||||
border-left: numbers.$tab-border-width solid colours.$tab-border-color;
|
||||
border-top: numbers.$tab-border-width solid colours.$tab-border-color;
|
||||
border-right: numbers.$tab-border-width solid colours.$tab-border-color;
|
||||
border-bottom: 0;
|
||||
top: numbers.$tab-border-width*2;
|
||||
background: assets.$tab-background;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
section.sheet-body {
|
||||
|
||||
border: numbers.$tab-border-width solid colours.$tab-border-color;
|
||||
background: assets.$tab-pane-background;
|
||||
|
||||
div.tab {
|
||||
|
||||
overflow: auto;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Tabs v2
|
||||
|
||||
.sheet-tabs {
|
||||
|
||||
position: relative;
|
||||
display: flow;
|
||||
border-top: unset;
|
||||
border-bottom: unset;
|
||||
margin-bottom: 0;
|
||||
|
||||
a[data-action="tab"] {
|
||||
|
||||
background-color: colours.$tab-inactive-background-color;
|
||||
display: inline-block;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
vertical-align: middle;
|
||||
padding: 0 16px;
|
||||
|
||||
span {
|
||||
|
||||
}
|
||||
|
||||
&.active {
|
||||
|
||||
border-left: numbers.$tab-border-width solid colours.$tab-border-color;
|
||||
border-top: numbers.$tab-border-width solid colours.$tab-border-color;
|
||||
border-right: numbers.$tab-border-width solid colours.$tab-border-color;
|
||||
border-bottom: 0;
|
||||
top: numbers.$tab-border-width;
|
||||
background: assets.$tab-background;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
box-shadow: numbers.$tab-shadow-right numbers.$tab-shadow-bottom numbers.$tab-shadow-blur-radius colours.$tab-shadow;
|
||||
|
||||
span {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
section.tab {
|
||||
border: numbers.$tab-border-width solid colours.$tab-border-color;
|
||||
background: assets.$tab-pane-background;
|
||||
box-shadow: numbers.$tab-pane-shadow-right numbers.$tab-pane-shadow-bottom numbers.$tab-pane-shadow-blur-radius colours.$tab-pane-shadow;
|
||||
|
||||
flex: 1;
|
||||
|
||||
& > div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
gap: 8px;
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -14,6 +14,11 @@
|
|||
height: 48px;
|
||||
line-height: 48px;
|
||||
}
|
||||
|
||||
button {
|
||||
height: 48px;
|
||||
width: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
.meta {
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
@use "sass:color";
|
||||
@use "../atoms/numbers";
|
||||
@use "../atoms/colours" as colour;
|
||||
@use "./character-tabs/meta";
|
||||
@use "./character-tabs/social";
|
||||
@use "./character-tabs/attributes";
|
||||
@use "./character-tabs/inventory";
|
||||
@use "./character-tabs/combat";
|
||||
@use "./character-tabs/spells";
|
||||
@use "./character-tabs/liturgies";
|
||||
@use "./character-tabs/skills";
|
||||
|
||||
.application.sheet.dsa41.actor.character {
|
||||
|
||||
$sidebar-width: 224px;
|
||||
$attribute-height: 60px;
|
||||
$tabs-spacing: 14px;
|
||||
$tabs-height: 26px;
|
||||
|
||||
.window-content {
|
||||
display: unset; /* we are on our own */
|
||||
position: relative;
|
||||
|
||||
.header-fields {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: $attribute-height;
|
||||
right: 0;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr max-content;
|
||||
gap: 0 8px;
|
||||
|
||||
.name {
|
||||
border: unset;
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
div.head-data {
|
||||
position: absolute;
|
||||
left: 16px;
|
||||
top: $attribute-height+30px;
|
||||
width: $sidebar-width - 16px;
|
||||
bottom: 16px;
|
||||
padding: 0;
|
||||
|
||||
|
||||
.profile-img {
|
||||
width: $sidebar-width - 16px;
|
||||
}
|
||||
}
|
||||
|
||||
nav.sheet-tabs.tabs {
|
||||
position: absolute;
|
||||
left: $sidebar-width+16px;
|
||||
top: $attribute-height+$tabs-spacing+13px;
|
||||
right: 16px;
|
||||
height: $tabs-height;
|
||||
}
|
||||
|
||||
section.tab {
|
||||
position: absolute;
|
||||
top: $attribute-height+$tabs-height+$tabs-spacing+21px;
|
||||
left: $sidebar-width+16px;
|
||||
right: 16px;
|
||||
bottom: 16px;
|
||||
padding: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.tab.meta.active {
|
||||
@include meta.tab;
|
||||
}
|
||||
|
||||
.tab.social.active {
|
||||
@include social.tab;
|
||||
}
|
||||
|
||||
.tab.attributes.active {
|
||||
@include attributes.tab;
|
||||
}
|
||||
|
||||
.tab.equipment.active {
|
||||
@include inventory.tab;
|
||||
}
|
||||
|
||||
.tab.combat.active {
|
||||
@include combat.tab;
|
||||
}
|
||||
|
||||
.tab.skills.active {
|
||||
@include skills.tab;
|
||||
}
|
||||
|
||||
.tab.spells {
|
||||
@include spells.tab;
|
||||
}
|
||||
|
||||
.tab.liturgies {
|
||||
@include liturgies.tab;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
@use "../atoms/colours" as colour;
|
||||
@use 'sass:color';
|
||||
@use "../atoms/numbers";
|
||||
|
||||
.dsa41.sheet.actor.creature {
|
||||
|
||||
.window-content {
|
||||
|
||||
.sheet-header {
|
||||
|
||||
height: 64px;
|
||||
display: grid;
|
||||
grid-template-columns: 64px 1fr;
|
||||
grid-template-rows: 1fr;
|
||||
gap: 0 8px;
|
||||
margin-bottom: 8px;
|
||||
|
||||
img {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
input {
|
||||
line-height: 64px;
|
||||
height: 64px;
|
||||
font-size: 2rem;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
div.input {
|
||||
|
||||
height: 32px;
|
||||
display: grid;
|
||||
grid-template-columns: 120px 1fr;
|
||||
|
||||
&.compound {
|
||||
|
||||
grid-template-columns: 120px 140px 1fr;
|
||||
|
||||
span {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
|
||||
input {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
label {
|
||||
height: 32px;
|
||||
width: 100%;
|
||||
|
||||
span {
|
||||
width: 120px;
|
||||
text-align: left;
|
||||
line-height: 32px;
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
input {
|
||||
text-align: right;
|
||||
line-height: 32px;
|
||||
vertical-align: middle;
|
||||
padding-left: 120px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
table.attacks-table {
|
||||
|
||||
margin: 0;
|
||||
|
||||
td {
|
||||
padding: 2px 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.rollable.tablecell {
|
||||
position: relative;
|
||||
|
||||
|
||||
.attacks-die {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
position: absolute;
|
||||
left: 4px;
|
||||
top: 4px;
|
||||
bottom: 2px;
|
||||
z-index: 1;
|
||||
|
||||
|
||||
svg {
|
||||
stroke-width: 0.5;
|
||||
|
||||
$color: #f30;
|
||||
|
||||
.border {
|
||||
fill: #0000;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
input {
|
||||
position: absolute;
|
||||
left: 16px;
|
||||
top: 4px;
|
||||
bottom: 2px;
|
||||
right: 4px;
|
||||
width: unset;
|
||||
text-indent: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.button-inline {
|
||||
border: unset;
|
||||
background: unset;
|
||||
}
|
||||
|
||||
.editor {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.tab.attacks.active {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
.application.sheet.dsa41.item.culture {
|
||||
|
||||
section.culture {
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
|
||||
div {
|
||||
flex: 0;
|
||||
}
|
||||
|
||||
div.editor {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
label {
|
||||
flex: 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,28 +1,15 @@
|
|||
@use "./_colours";
|
||||
@use "./_numbers";
|
||||
@use "../atoms/colours";
|
||||
@use "../atoms/numbers";
|
||||
|
||||
.app.window-app.dsa41.sheet.item.equipment {
|
||||
.application.sheet.dsa41.item.equipment {
|
||||
|
||||
.sheet-body {
|
||||
.tab.meta.active > div {
|
||||
|
||||
position: relative;
|
||||
|
||||
.tab.active {
|
||||
padding: 4px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.tab.meta.active {
|
||||
|
||||
position: absolute;
|
||||
display: grid;
|
||||
grid-auto-columns: 1fr 1fr;
|
||||
grid-template-columns: 80px auto;
|
||||
grid-template-rows: 24px 48px auto 48px;
|
||||
gap: 0 0;
|
||||
grid-template-rows: 32px 48px auto 48px;
|
||||
gap: 8px;
|
||||
grid-template-areas:
|
||||
"category category"
|
||||
"quantity name"
|
||||
|
|
@ -57,6 +44,7 @@
|
|||
grid-area: bottomline;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 8px;
|
||||
|
||||
.named-value {
|
||||
position: relative;
|
||||
|
|
@ -104,7 +92,7 @@
|
|||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
padding: 0 32px 0 0;
|
||||
margin: 0;
|
||||
text-indent: 0;
|
||||
|
||||
|
|
@ -124,6 +112,7 @@
|
|||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -153,7 +142,4 @@
|
|||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,40 +1,14 @@
|
|||
.dsa41.sheet.actor.group {
|
||||
|
||||
|
||||
.window-content {
|
||||
display: unset;
|
||||
position: relative;
|
||||
}
|
||||
.application.sheet.dsa41.actor.group {
|
||||
|
||||
.sheet-header {
|
||||
.sheet-name {
|
||||
font-size: 24pt;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
}
|
||||
display: grid;
|
||||
grid-template-columns: 32px 1fr;
|
||||
gap: 8px;
|
||||
|
||||
.sheet-tabs {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 76px;
|
||||
height: 32px;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.sheet-body {
|
||||
position: absolute;
|
||||
top: 98px;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
padding: 8px;
|
||||
margin: 8px;
|
||||
|
||||
div.tab {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
img {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
.application.sheet.dsa41.item.profession {
|
||||
|
||||
section.profession {
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
|
||||
div {
|
||||
flex: 0;
|
||||
}
|
||||
|
||||
div.editor {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
label {
|
||||
flex: 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
.sheet.item.skill {
|
||||
.dsa41.sheet.item.skill {
|
||||
|
||||
.tab.meta.active {
|
||||
.meta-details {
|
||||
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
|
|
@ -8,9 +8,7 @@
|
|||
"taw statistics ebe"
|
||||
"language language language"
|
||||
"attack attack attack";
|
||||
|
||||
gap: 8px;
|
||||
margin: 8px;
|
||||
height: unset;
|
||||
|
||||
.category {
|
||||
grid-area: category;
|
||||
|
|
@ -44,8 +42,13 @@
|
|||
grid-area: attack;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.description-details {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
.application.sheet.dsa41.item.species {
|
||||
|
||||
section.species {
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
|
||||
div {
|
||||
flex: 0;
|
||||
}
|
||||
|
||||
div.editor {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
label {
|
||||
flex: 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue