Compare commits
4 Commits
ced57dbbcb
...
6133cc2237
| Author | SHA1 | Date |
|---|---|---|
|
|
6133cc2237 | |
|
|
169e41d2c8 | |
|
|
faa3bc1328 | |
|
|
5b76df3653 |
|
|
@ -1,2 +1,3 @@
|
|||
dist
|
||||
node_modules
|
||||
src/packs/__source
|
||||
|
|
|
|||
|
|
@ -5,8 +5,10 @@
|
|||
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/src/packs/__source" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/src/packs/__source" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
</module>
|
||||
|
|
|
|||
79
gulpfile.mjs
|
|
@ -1,23 +1,70 @@
|
|||
import {dest, series, src} from 'gulp';
|
||||
import process from 'node:process';
|
||||
import replace from 'gulp-replace';
|
||||
|
||||
import {getRandomValues} from 'node:crypto';
|
||||
import * as dartSass from 'sass';
|
||||
import gulpSass from 'gulp-sass';
|
||||
import {deleteAsync} from 'del';
|
||||
|
||||
import {readdirSync} from 'node:fs';
|
||||
import {readdirSync, readFileSync, writeFileSync, rmdirSync, existsSync, mkdirSync} from "fs";
|
||||
import {join} from 'node:path';
|
||||
|
||||
import {compilePack} from '@foundryvtt/foundryvtt-cli';
|
||||
|
||||
const sass = gulpSass(dartSass);
|
||||
|
||||
|
||||
/**
|
||||
* Generate a random alphanumeric string ID of a given requested length using `crypto.getRandomValues()`.
|
||||
* @param {number} length The length of the random string to generate, which must be at most 16384.
|
||||
* @returns {string} A string containing random letters (A-Z, a-z) and numbers (0-9).
|
||||
*/
|
||||
function randomID(length = 16) {
|
||||
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
const cutoff = 0x100000000 - (0x100000000 % chars.length);
|
||||
const random = new Uint32Array(length);
|
||||
do {
|
||||
getRandomValues(random);
|
||||
} while (random.some(x => x >= cutoff));
|
||||
let id = "";
|
||||
for (let i = 0; i < length; i++) id += chars[random[i] % chars.length];
|
||||
return id;
|
||||
}
|
||||
|
||||
const convert = function (from, to, ofType) {
|
||||
|
||||
const SOURCE = from;
|
||||
const DEST = to;
|
||||
const TYPE = ofType;
|
||||
|
||||
try {
|
||||
rmdirSync(DEST, {force: true, recursive: true})
|
||||
} catch (e) {
|
||||
}
|
||||
mkdirSync(DEST)
|
||||
|
||||
readdirSync(SOURCE).forEach(file => {
|
||||
let originalSource = JSON.parse(readFileSync(join(SOURCE, file), {encoding: "utf8"}));
|
||||
let id = randomID();
|
||||
let targetSource = {
|
||||
_id: id,
|
||||
_key: "!items!" + id,
|
||||
type: TYPE,
|
||||
img: originalSource.image,
|
||||
name: originalSource.name.trim(),
|
||||
system: {...originalSource}
|
||||
}
|
||||
delete targetSource.system.image;
|
||||
let target = JSON.stringify(targetSource, null, 2);
|
||||
let newFileName = "./" + join(DEST, id + ".json");
|
||||
writeFileSync(newFileName, target, {encoding: "utf8"});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function cleanDist() {
|
||||
return deleteAsync(['dist/**']);
|
||||
}
|
||||
|
||||
|
||||
function buildStyles() {
|
||||
return src('src/style/**/*.scss')
|
||||
.pipe(sass().on('error', sass.logError))
|
||||
|
|
@ -40,6 +87,27 @@ function updateManifestFile() {
|
|||
.pipe(dest('dist/'))
|
||||
}
|
||||
|
||||
async function prepareDB() {
|
||||
|
||||
try {
|
||||
if (!existsSync("./src/packs/__source")) {
|
||||
mkdirSync("./src/packs/__source");
|
||||
}
|
||||
|
||||
convert("./src/packs/_source/talente", "./src/packs/__source/talente", "Skill");
|
||||
convert("./src/packs/_source/zauber", "./src/packs/__source/zauber", "Spell");
|
||||
convert("./src/packs/_source/vorteile", "./src/packs/__source/vorteile", "Advantage");
|
||||
convert("./src/packs/_source/waffen", "./src/packs/__source/waffen", "Equipment");
|
||||
convert("./src/packs/_source/munition", "./src/packs/__source/munition", "Equipment");
|
||||
convert("./src/packs/_source/ruestzeug", "./src/packs/__source/ruestzeug", "Equipment");
|
||||
convert("./src/packs/_source/liturgien-und-segnungen", "./src/packs/__source/liturgien", "Liturgy");
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function buildDB() {
|
||||
// Determine which source folders to process
|
||||
|
||||
|
|
@ -55,7 +123,7 @@ function buildDB() {
|
|||
const src = join(PACK_SRC, folder.name);
|
||||
const dest = join(PACK_DEST, folder.name);
|
||||
console.info(`Compiling pack ${folder.name}`);
|
||||
await compilePack(src, dest, {recursive: true, log: true, nedb: false});
|
||||
await compilePack(src, dest, {recursive: true, nedb: false});
|
||||
|
||||
}
|
||||
resolve()
|
||||
|
|
@ -68,6 +136,7 @@ export default series(
|
|||
copySource,
|
||||
copyAssets,
|
||||
buildStyles,
|
||||
prepareDB,
|
||||
buildDB,
|
||||
updateManifestFile
|
||||
)
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 500 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 87 KiB |
33
src/main.mjs
|
|
@ -13,6 +13,13 @@ import {EquipmentDataModel} from "./module/data/equipment.mjs";
|
|||
import {AusruestungSheet} 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";
|
||||
import {LiturgyDataModel} from "./module/data/liturgy.mjs";
|
||||
import {BlessingDataModel} from "./module/data/blessing.mjs";
|
||||
import {SpecialAbilityDataModel} from "./module/data/specialAbility.mjs";
|
||||
import {SpecialAbilitySheet} from "./module/sheets/specialAbilitySheet.mjs";
|
||||
import {ActiveEffectSheet} from "./module/sheets/ActiveEffectSheet.mjs";
|
||||
import {ActiveEffectDataModel} from "./module/data/activeeffect.mjs";
|
||||
|
||||
async function preloadHandlebarsTemplates() {
|
||||
return loadTemplates([
|
||||
|
|
@ -23,10 +30,12 @@ async function preloadHandlebarsTemplates() {
|
|||
'systems/DSA_4-1/templates/ui/partial-talent-editable.hbs',
|
||||
'systems/DSA_4-1/templates/ui/partial-die.hbs',
|
||||
'systems/DSA_4-1/templates/ui/partial-advantage-button.hbs',
|
||||
'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/ui/partial-array-editor.hbs',
|
||||
'systems/DSA_4-1/templates/dialog/modify-liturgy.hbs'
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -51,6 +60,10 @@ Hooks.once("init", () => {
|
|||
Spell: SpellDataModel,
|
||||
Advantage: VornachteileDataModel,
|
||||
Equipment: EquipmentDataModel,
|
||||
Liturgy: LiturgyDataModel,
|
||||
Blessing: BlessingDataModel,
|
||||
SpecialAbility: SpecialAbilityDataModel,
|
||||
ActiveEffect: ActiveEffectDataModel,
|
||||
}
|
||||
|
||||
CONFIG.Combat.initiative = {
|
||||
|
|
@ -94,9 +107,25 @@ Hooks.once("init", () => {
|
|||
})
|
||||
Items.registerSheet('dsa41.equipment', AusruestungSheet, {
|
||||
types: ["Equipment"],
|
||||
makeDefault: true,
|
||||
makeDefault: false,
|
||||
label: 'DSA41.AusruestungLabels.Item'
|
||||
})
|
||||
Items.registerSheet('dsa41.liturgy', LiturgySheet, {
|
||||
types: ["SpecialAbility"],
|
||||
makeDefault: true,
|
||||
label: 'DSA41.SpecialAbilityLabels.Item'
|
||||
})
|
||||
Items.registerSheet('dsa41.specialAbility', SpecialAbilitySheet, {
|
||||
types: ["Liturgy"],
|
||||
makeDefault: true,
|
||||
label: 'DSA41.LiturgyLabels.Item'
|
||||
})
|
||||
|
||||
Items.registerSheet('dsa41.activeEffect', ActiveEffectSheet, {
|
||||
types: ['ActiveEffect'],
|
||||
makeDefault: true,
|
||||
label: 'DSA41.ActiveEffectLabels.ActiveFfect'
|
||||
})
|
||||
|
||||
return preloadHandlebarsTemplates();
|
||||
})
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
import BaseItem from "./base-item.mjs";
|
||||
|
||||
const {ArrayField, NumberField, StringField, HTMLField} = foundry.data.fields;
|
||||
|
||||
export class ActiveEffectDataModel extends BaseItem {
|
||||
|
||||
static defineSchema() {
|
||||
return {
|
||||
name: new StringField({required: true}),
|
||||
notes: new HTMLField(),
|
||||
}
|
||||
/*
|
||||
|
||||
name: String, // Name of Vornachteil will be used for rendering and referencing by other Items
|
||||
description: HTMLString, // only used for rendering
|
||||
variant: [String]?, // variant name of Vornachteil e.g. "Mut" in the case of "Herausragende Eigenschaft"
|
||||
levels: [Number]?, // available levels e.g. 1, 2 in the case of "Flink"
|
||||
mods: [
|
||||
{
|
||||
level: Number?, // in reference to level of the Vornachteil, is null when it does not have any levels or is the only modification
|
||||
field: String, // Reference to Actor Data e.g. "FF" maps to "FF.mod"
|
||||
value: Number, // value of the Modification e.g. "+2" maps to 2
|
||||
requirement: {
|
||||
field: String // Reference to Actor Data e.g. "BE" maps "be.aktuell"
|
||||
operation: String // Supported: "<=", ">"
|
||||
value: Number // Target Value the referenced field has to compare against
|
||||
}? // optional when the mod does not have an active requirement
|
||||
}
|
||||
]
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
_onCreate(data, options, userId) {
|
||||
super._onCreate(data, options, userId);
|
||||
if (this.parent.getEmbeddedCollection("ActiveEffect").contents.length === 0) {
|
||||
|
||||
|
||||
this.parent.createEmbeddedDocuments("ActiveEffect", [{
|
||||
name: data.name,
|
||||
changes: [],
|
||||
duration: {},
|
||||
icon: this.img,
|
||||
}]);
|
||||
console.log("added default activeffect");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
const {
|
||||
SchemaField, NumberField, StringField, EmbeddedDocumentField, DocumentIdField, ArrayField, ForeignDocumentField
|
||||
} = foundry.data.fields;
|
||||
|
||||
export class BlessingDataModel extends foundry.abstract.TypeDataModel {
|
||||
|
||||
static defineSchema() {
|
||||
return {
|
||||
gottheit: new StringField(),
|
||||
wert: new NumberField({min: 0, integer: true}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,12 @@
|
|||
const {
|
||||
SchemaField, NumberField, StringField, EmbeddedDocumentField, DocumentIdField, ArrayField, ForeignDocumentField
|
||||
SchemaField,
|
||||
NumberField,
|
||||
StringField,
|
||||
HTMLField,
|
||||
EmbeddedDocumentField,
|
||||
DocumentIdField,
|
||||
ArrayField,
|
||||
ForeignDocumentField
|
||||
} = foundry.data.fields;
|
||||
|
||||
export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel {
|
||||
|
|
@ -13,16 +20,17 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel {
|
|||
professions: new ArrayField(new StringField()),
|
||||
geschlecht: new StringField(),
|
||||
haarfarbe: new StringField(),
|
||||
groesse: new NumberField({required: true, integer: false}),
|
||||
groesse: new StringField(),
|
||||
augenfarbe: new StringField(),
|
||||
geburtstag: new StringField(),
|
||||
alter: new NumberField({required: true, integer: true}),
|
||||
gewicht: new NumberField({required: true, integer: true}),
|
||||
aussehen: new ArrayField(new StringField()),
|
||||
familie: new ArrayField(new StringField()),
|
||||
alter: new StringField(),
|
||||
gewicht: new StringField(),
|
||||
aussehen: new HTMLField(),
|
||||
familie: new HTMLField(),
|
||||
titel: new StringField(),
|
||||
stand: new StringField(),
|
||||
}),
|
||||
setEquipped: new NumberField({required: true, initial: 0, max: 3, integer: true}),
|
||||
ini: new SchemaField({
|
||||
aktuell: new NumberField({required: true, integer: true, initial: 0}),
|
||||
mod: new NumberField({required: true, integer: true, initial: 0}),
|
||||
|
|
@ -107,23 +115,7 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel {
|
|||
}),
|
||||
gilde: new StringField(),
|
||||
}),
|
||||
vornachteile: new ArrayField(new SchemaField({
|
||||
vornachteil: new DocumentIdField(Item),
|
||||
wert: new NumberField({required: false, integer: true}),
|
||||
})),
|
||||
sonderfertigkeiten: new ArrayField(new SchemaField({
|
||||
name: new StringField(),
|
||||
auswahlen: new ArrayField(new StringField()),
|
||||
})),
|
||||
|
||||
talente: new ArrayField(new DocumentIdField(Item)),
|
||||
zauber: new ArrayField(new SchemaField({
|
||||
talent: new DocumentIdField(),
|
||||
zfw: new NumberField({integer: true, required: true}),
|
||||
})),
|
||||
liturgien: new ArrayField(new SchemaField({
|
||||
name: new StringField(),
|
||||
})),
|
||||
kampfwerte: new ArrayField(new SchemaField({
|
||||
name: new StringField(),
|
||||
at: new NumberField({required: true, integer: true}),
|
||||
|
|
@ -160,27 +152,22 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel {
|
|||
_initializeSource(data, options) {
|
||||
if (data.heldenausruestung.length === 0) {
|
||||
let sets = [];
|
||||
|
||||
for (let i = 0; i < 3; i++) {
|
||||
|
||||
const preppedSet = {}
|
||||
|
||||
PlayerCharacterDataModel.getSlots().forEach(slot => {
|
||||
preppedSet[slot] = null;
|
||||
})
|
||||
|
||||
sets.push(preppedSet);
|
||||
|
||||
}
|
||||
data.heldenausruestung = sets
|
||||
|
||||
}
|
||||
|
||||
return super._initializeSource(data, options);
|
||||
}
|
||||
|
||||
async _onCreate(data, options, userId) {
|
||||
|
||||
console.log(data, 'onCreate');
|
||||
|
||||
}
|
||||
|
||||
static getSlots() {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,12 @@
|
|||
const {
|
||||
SchemaField, NumberField, StringField, EmbeddedDocumentField, DocumentIdField, ArrayField, ForeignDocumentField
|
||||
SchemaField,
|
||||
ObjectField,
|
||||
NumberField,
|
||||
StringField,
|
||||
EmbeddedDocumentField,
|
||||
DocumentIdField,
|
||||
ArrayField,
|
||||
ForeignDocumentField
|
||||
} = foundry.data.fields;
|
||||
|
||||
export class GroupDataModel extends foundry.abstract.TypeDataModel {
|
||||
|
|
@ -13,7 +20,8 @@ export class GroupDataModel extends foundry.abstract.TypeDataModel {
|
|||
}),
|
||||
characters: new ArrayField(
|
||||
new DocumentIdField(Actor)
|
||||
)
|
||||
),
|
||||
settings: new ObjectField(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
import BaseItem from "./base-item.mjs";
|
||||
|
||||
const {BooleanField, NumberField, SchemaField, ArrayField, StringField, HTMLField} = foundry.data.fields;
|
||||
|
||||
export class LiturgyDataModel extends BaseItem {
|
||||
|
||||
static defineSchema() {
|
||||
return {
|
||||
herkunft: new ArrayField(new SchemaField({
|
||||
name: new StringField(),
|
||||
grad: new NumberField(),
|
||||
})),
|
||||
grad: new NumberField({min: 1, max: 5}),
|
||||
reichweite: new StringField(),
|
||||
ziel: new StringField(),
|
||||
wirkungsdauer: new StringField(),
|
||||
auswirkung: new SchemaField({
|
||||
I: new StringField(),
|
||||
II: new StringField(),
|
||||
III: new StringField(),
|
||||
IV: new StringField(),
|
||||
V: new StringField(),
|
||||
VI: new StringField(),
|
||||
VII: new StringField(),
|
||||
VIII: new StringField(),
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
prepareData() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare a data object which is passed to any Roll formulas which are created related to this Item
|
||||
* @private
|
||||
*/
|
||||
getRollData() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle clickable rolls.
|
||||
* @param {Event} event The originating click event
|
||||
* @private
|
||||
*/
|
||||
async roll() {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
export class LiturgyData {
|
||||
|
||||
static ranks = ["I", "II", "III", "IV", "V", "VI", "VII", "VIII"]
|
||||
|
||||
static #ranks = [
|
||||
{index: 0, name: "O", lkp: 3, mod: 2, costKaP: 2, costKaPPermant: 0, duration: "{*} KR", strength: "{*}/2"},
|
||||
{index: 1, name: "I", lkp: 3, mod: 0, costKaP: 5, costKaPPermant: 0, duration: "{*} KR", strength: "{*}/2"},
|
||||
{
|
||||
index: 2,
|
||||
name: "II",
|
||||
lkp: 6,
|
||||
mod: -2,
|
||||
costKaP: 10,
|
||||
costKaPPermant: 0,
|
||||
duration: "{*}*10 KR",
|
||||
strength: "{*}/2+5"
|
||||
},
|
||||
{index: 3, name: "III", lkp: 9, mod: -4, costKaP: 15, costKaPPermant: 0, duration: "{*} SR", strength: "{*}+5"},
|
||||
{
|
||||
index: 4,
|
||||
name: "IV",
|
||||
lkp: 12,
|
||||
mod: -6,
|
||||
costKaP: 20,
|
||||
costKaPPermant: 0,
|
||||
duration: "{*} Stunden",
|
||||
strength: "{*}+10"
|
||||
},
|
||||
{
|
||||
index: 5,
|
||||
name: "V",
|
||||
lkp: 15,
|
||||
mod: -8,
|
||||
costKaP: 25,
|
||||
costKaPPermant: 1,
|
||||
duration: "{*} Tage",
|
||||
strength: "{*}+15"
|
||||
},
|
||||
{
|
||||
index: 6,
|
||||
name: "VI",
|
||||
lkp: 18,
|
||||
mod: -10,
|
||||
costKaP: 30,
|
||||
costKaPPermant: 3,
|
||||
duration: "{*} Wochen",
|
||||
strength: "{*}+20"
|
||||
},
|
||||
{
|
||||
index: 7,
|
||||
name: "VII",
|
||||
lkp: 21,
|
||||
mod: -12,
|
||||
costKaP: 35,
|
||||
costKaPPermant: 5,
|
||||
duration: "{*} Monate",
|
||||
strength: "{*}+25"
|
||||
},
|
||||
{
|
||||
index: 8,
|
||||
name: "VIII",
|
||||
lkp: 24,
|
||||
mod: -14,
|
||||
costKaP: 40,
|
||||
costKaPPermant: 7,
|
||||
duration: "{*} Jahre oder permanent",
|
||||
casttime: "",
|
||||
strength: "{*}+30"
|
||||
},
|
||||
];
|
||||
|
||||
static alverans = [
|
||||
"Praios",
|
||||
"Rondra",
|
||||
"Efferd",
|
||||
"Travia",
|
||||
"Boron",
|
||||
"Hesinde",
|
||||
"Firun",
|
||||
"Tsa",
|
||||
"Phex",
|
||||
"Peraine",
|
||||
"Ingerimm",
|
||||
"Rahja"
|
||||
]
|
||||
|
||||
static #aliases = [
|
||||
{
|
||||
"originalName": "Handwerkssegen",
|
||||
"aliases": ["Cereborns Handreichung", "Hauch der Leidenschaft"]
|
||||
},
|
||||
{
|
||||
"originalName": "Heiliger Befehl",
|
||||
"aliases": ["Wort der Wahrheit"],
|
||||
},
|
||||
{
|
||||
"originalName": "Eidsegen",
|
||||
"aliases": ["Lehnseid"],
|
||||
}
|
||||
]
|
||||
|
||||
static getRankOfLiturgy(liturgy, deity) {
|
||||
const lookupData = liturgy.herkunft.find(p => p.name === deity)
|
||||
const rank = lookupData?.grad;
|
||||
return LiturgyData.#ranks[rank];
|
||||
}
|
||||
|
||||
static lookupAlias(alias) {
|
||||
return LiturgyData.#aliases.find((entry) => {
|
||||
console.log(alias, entry.aliases.indexOf(alias) !== -1)
|
||||
return entry.aliases.indexOf(alias) !== -1
|
||||
})?.originalName ?? alias; // cant determine thus simply return the original query name
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import BaseItem from "./base-item.mjs";
|
||||
|
||||
const {BooleanField, NumberField, SchemaField, ArrayField, StringField, HTMLField} = foundry.data.fields;
|
||||
|
||||
export class SpecialAbilityDataModel extends BaseItem {
|
||||
|
||||
static defineSchema() {
|
||||
return {
|
||||
name: new StringField()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,9 +7,11 @@ export class SpellDataModel extends BaseItem {
|
|||
static defineSchema() {
|
||||
return {
|
||||
seite: new NumberField(),
|
||||
zfw: new NumberField(),
|
||||
name: new StringField({required: true}),
|
||||
probe: new ArrayField(new StringField(), {required: true, exact: 3}),
|
||||
probeMod: new StringField(),
|
||||
hauszauber: new BooleanField(),
|
||||
technik: new StringField(),
|
||||
zauberdauer: new StringField(),
|
||||
wirkung: new StringField(),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,89 @@
|
|||
import {LiturgyData} from "../data/miracle/liturgydata.mjs";
|
||||
|
||||
export class ModifyLiturgy {
|
||||
|
||||
static data = {}
|
||||
static naming = {
|
||||
"range": "Reichweite",
|
||||
"strength": "Wirkung",
|
||||
"target": "Ziele",
|
||||
"castduration": "Wirkzeit",
|
||||
"duration": "Wirkdauer"
|
||||
}
|
||||
|
||||
constructor(data) {
|
||||
ModifyLiturgy.data = data;
|
||||
ModifyLiturgy.data.maxmods = Math.round(data.lkp / 3);
|
||||
ModifyLiturgy.data.variation = null;
|
||||
console.log("ModifyLiturgy constructed", data)
|
||||
}
|
||||
|
||||
static renderMods(html) {
|
||||
|
||||
let result = '';
|
||||
|
||||
ModifyLiturgy.data.mods.forEach(((mod, index) => {
|
||||
|
||||
result += `<tr><td>${LiturgyData.ranks[mod.rank]}</td><td>${ModifyLiturgy.naming[mod.mod]}</td><td><button class="remove-mod" data-index="${index}"><i class="fa-solid fa-xmark"></i></button></td></tr>`
|
||||
}))
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
handleRender(html) {
|
||||
|
||||
|
||||
html.off('click', 'input[name="data.variation"]')
|
||||
html.on('click', 'input[name="data.variation"]', (evt) => {
|
||||
if (evt.currentTarget.checked) {
|
||||
ModifyLiturgy.data.variation = evt.currentTarget.dataset['rank'];
|
||||
ModifyLiturgy.data.mods = [];
|
||||
}
|
||||
this.render(html)
|
||||
})
|
||||
html.off('click', 'button[class="remove-mod"]')
|
||||
html.on('click', 'button[class="remove-mod"]', (evt) => {
|
||||
const {index} = evt.currentTarget.dataset;
|
||||
ModifyLiturgy.data.mods.splice(index, 1);
|
||||
this.render(html)
|
||||
})
|
||||
html.off('change', 'select[name="mod"]')
|
||||
html.on('change', 'select[name="mod"]', (evt) => {
|
||||
const value = evt.currentTarget.value;
|
||||
if (value === '') return;
|
||||
const currentRank = ModifyLiturgy.data.mods.length + Number(ModifyLiturgy.data.rank);
|
||||
ModifyLiturgy.data.mods.push({
|
||||
rank: currentRank,
|
||||
mod: value,
|
||||
});
|
||||
evt.currentTarget.value = "";
|
||||
this.render(html)
|
||||
})
|
||||
|
||||
// render state
|
||||
$('#mods', html).html(ModifyLiturgy.renderMods(html))
|
||||
|
||||
|
||||
// state handling
|
||||
|
||||
if (ModifyLiturgy.data.mods.length === ModifyLiturgy.data.maxmods) {
|
||||
$(".editor, .editor *", html).attr('disabled', 'disabled');
|
||||
$(".editor select", html).hide();
|
||||
$('span#info', html).text('LkW lässt keine weitere Modifikationen zu')
|
||||
$("#mod_rank", html).text(LiturgyData.ranks[ModifyLiturgy.data.mods.length + Number(ModifyLiturgy.data.rank)]);
|
||||
} else if (ModifyLiturgy.data.variation == null) {
|
||||
$(".editor select *", html).attr('disabled', 'disabled');
|
||||
$(".editor select", html).hide();
|
||||
$('span#info', html).text('Keine Variante ausgewählt')
|
||||
$("#mod_rank", html).text('');
|
||||
} else {
|
||||
$(".editor, .editor *", html).removeAttr('disabled');
|
||||
$(".editor select", html).show();
|
||||
$('span#info', html).text('')
|
||||
$("#mod_rank", html).text('');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
export class Blessing extends Item {
|
||||
/**
|
||||
* Augment the basic Item data model with additional dynamic data.
|
||||
*/
|
||||
prepareData() {
|
||||
super.prepareData();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
import {importCharacter} from "../xml-import/xml-import.mjs";
|
||||
import {LiturgyData} from "../data/miracle/liturgydata.mjs";
|
||||
|
||||
export class Character extends Actor {
|
||||
|
||||
|
|
@ -27,27 +28,80 @@ export class Character extends Actor {
|
|||
const actorData = this;
|
||||
const systemData = actorData.system;
|
||||
|
||||
const mu = systemData.attribute.mu.aktuell;
|
||||
const kl = systemData.attribute.kl.aktuell;
|
||||
const _in = systemData.attribute.in.aktuell;
|
||||
const ch = systemData.attribute.ch.aktuell;
|
||||
const mu = systemData.attribute.mu.aktuell + systemData.attribute.mu.mod;
|
||||
const kl = systemData.attribute.kl.aktuell + systemData.attribute.kl.mod;
|
||||
const _in = systemData.attribute.in.aktuell + systemData.attribute.in.mod;
|
||||
const ch = systemData.attribute.ch.aktuell + systemData.attribute.ch.mod;
|
||||
|
||||
const ff = systemData.attribute.ff.aktuell;
|
||||
const ge = systemData.attribute.ge.aktuell;
|
||||
const ko = systemData.attribute.kk.aktuell;
|
||||
const kk = systemData.attribute.kk.aktuell;
|
||||
const ff = systemData.attribute.ff.aktuell + systemData.attribute.ff.mod;
|
||||
const ge = systemData.attribute.ge.aktuell + systemData.attribute.ge.mod;
|
||||
const ko = systemData.attribute.kk.aktuell + systemData.attribute.ko.mod;
|
||||
const kk = systemData.attribute.kk.aktuell + systemData.attribute.kk.mod;
|
||||
|
||||
|
||||
systemData.lep.max = Math.round((ko + ko + kk) / 2) + systemData.lep.mod;
|
||||
systemData.aup.max = Math.round((mu + ko + ge) / 2) + systemData.aup.mod;
|
||||
systemData.asp.max = Math.round((mu + _in + ch) / 2) + systemData.asp.mod;
|
||||
|
||||
|
||||
systemData.at = Math.round((mu + ge + kk) / 5);
|
||||
systemData.pa = Math.round((_in + ge + kk) / 5);
|
||||
systemData.fk = Math.round((_in + ff + kk) / 5);
|
||||
|
||||
systemData.ini.aktuell = Math.round((mu + mu + _in + ge) / 5) + systemData.ini.mod;
|
||||
systemData.mr.aktuell = Math.round((mu + kl + ko) / 5) + systemData.mr.mod;
|
||||
|
||||
systemData.rs = 0;
|
||||
systemData.be = 0;
|
||||
|
||||
// map current set to RS and BE
|
||||
|
||||
const ausruestung = systemData.heldenausruestung[systemData.setEquipped];
|
||||
if (ausruestung) {
|
||||
if (ausruestung.brust) {
|
||||
systemData.rs += systemData.parent.items.get(ausruestung.brust).system.armorValue ?? 0
|
||||
systemData.be += systemData.parent.items.get(ausruestung.brust).system.armorHandicap ?? 0
|
||||
}
|
||||
if (ausruestung.bauch) {
|
||||
systemData.rs += systemData.parent.items.get(ausruestung.bauch).system.armorValue ?? 0
|
||||
systemData.be += systemData.parent.items.get(ausruestung.bauch).system.armorHandicap ?? 0
|
||||
}
|
||||
if (ausruestung.ruecken) {
|
||||
systemData.rs += systemData.parent.items.get(ausruestung.ruecken).system.armorValue ?? 0
|
||||
systemData.be += systemData.parent.items.get(ausruestung.ruecken).system.armorHandicap ?? 0
|
||||
}
|
||||
if (ausruestung.armlinks) {
|
||||
systemData.rs += systemData.parent.items.get(ausruestung.armlinks).system.armorValue ?? 0
|
||||
systemData.be += systemData.parent.items.get(ausruestung.armlinks).system.armorHandicap ?? 0
|
||||
}
|
||||
if (ausruestung.armrechts) {
|
||||
systemData.rs += systemData.parent.items.get(ausruestung.armrechts).system.armorValue ?? 0
|
||||
systemData.be += systemData.parent.items.get(ausruestung.armrechts).system.armorHandicap ?? 0
|
||||
}
|
||||
if (ausruestung.beinlinks) {
|
||||
systemData.rs += systemData.parent.items.get(ausruestung.beinlinks).system.armorValue ?? 0
|
||||
systemData.be += systemData.parent.items.get(ausruestung.beinlinks).system.armorHandicap ?? 0
|
||||
}
|
||||
if (ausruestung.beinrechts) {
|
||||
systemData.rs += systemData.parent.items.get(ausruestung.beinrechts).system.armorValue ?? 0
|
||||
systemData.be += systemData.parent.items.get(ausruestung.beinrechts).system.armorHandicap ?? 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
systemData.kap.max = 0;
|
||||
|
||||
// evaluate deities for KaP
|
||||
|
||||
const deities = systemData.parent.items.filter(p => p.type === "Blessing")
|
||||
deities?.forEach((deity) => {
|
||||
if (LiturgyData.alverans.includes(deity.system.gottheit)) {
|
||||
systemData.kap.max = 24;
|
||||
} else if (systemData.kap.max === 0) {
|
||||
systemData.kap.max += 12;
|
||||
}
|
||||
}, 0)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
export class Liturgy extends Item {
|
||||
/**
|
||||
* Augment the basic Item data model with additional dynamic data.
|
||||
*/
|
||||
prepareData() {
|
||||
super.prepareData();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
export class SpecialAbility extends Item {
|
||||
/**
|
||||
* Augment the basic Item data model with additional dynamic data.
|
||||
*/
|
||||
prepareData() {
|
||||
super.prepareData();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
export class ActiveEffectSheet extends ItemSheet {
|
||||
/**@override */
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ['dsa41', 'sheet', 'activeeffect'],
|
||||
width: 520,
|
||||
height: 480
|
||||
});
|
||||
}
|
||||
|
||||
/** @override */
|
||||
get template() {
|
||||
return `systems/DSA_4-1/templates/item/item-activeeffect-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();
|
||||
const effects = context.document.getEmbeddedCollection("ActiveEffect").contents;
|
||||
if (effects.length > 0) {
|
||||
context.effectId = effects[0]._id;
|
||||
}
|
||||
|
||||
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);
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -202,11 +202,11 @@ export class ActionManager {
|
|||
]
|
||||
|
||||
#hatSonderfertigkeitBeginnendMit(name) {
|
||||
return this.actor.system.sonderfertigkeiten.find(p => p.name.startsWith(name)) != null
|
||||
return this.actor.system.sonderfertigkeiten?.find(p => p.name.startsWith(name)) != null
|
||||
}
|
||||
|
||||
#hatSonderfertigkeit(name) {
|
||||
return this.actor.system.sonderfertigkeiten.find(p => p.name === name) != null
|
||||
return this.actor.system.sonderfertigkeiten?.find(p => p.name === name) != null
|
||||
}
|
||||
|
||||
evaluate() {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ import {rollAttributeForActor} from "../utils/rolls/rollEngine.mjs";
|
|||
|
||||
import {PlayerCharacterDataModel} from "../data/character.mjs";
|
||||
import {ActionManager} from "./actions/action-manager.mjs";
|
||||
import {LiturgyData} from "../data/miracle/liturgydata.mjs";
|
||||
import {ModifyLiturgy} from "../dialog/modify-liturgy.mjs";
|
||||
|
||||
export class CharacterSheet extends ActorSheet {
|
||||
/**@override */
|
||||
|
|
@ -25,25 +27,32 @@ export class CharacterSheet extends ActorSheet {
|
|||
return `systems/DSA_4-1/templates/actor/actor-character-sheet.hbs`;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async getData() {
|
||||
const context = super.getData();
|
||||
static onDroppedData(actor, characterSheet, data) {
|
||||
const uuid = foundry.utils.parseUuid(data.uuid);
|
||||
const collection = uuid.collection.index ?? uuid.collection;
|
||||
const document = CharacterSheet.getElementByName(collection, uuid.id);
|
||||
const {
|
||||
name,
|
||||
type
|
||||
} = document
|
||||
console.log(name, type)
|
||||
switch (type) {
|
||||
case "Skill":
|
||||
return characterSheet.#handleDroppedSkill(actor, document); // on false cancel this whole operation
|
||||
case "Advantage":
|
||||
return characterSheet.#handleDroppedAdvantage(actor, document);
|
||||
case "ActiveEffect":
|
||||
return characterSheet.#handleDroppedActiveEffect(actor, document);
|
||||
case "Equipment":
|
||||
return characterSheet.#handleDroppedEquipment(actor, document);
|
||||
case "Liturgy":
|
||||
return characterSheet.#handleDroppedLiturgy(actor, document);
|
||||
case "SpecialAbility":
|
||||
return characterSheet.#handleDroppedSpecialAbility(actor, document);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Use a safe clone of the actor data for further operations.
|
||||
const actorData = context.data;
|
||||
|
||||
// Add the actor's data to context.data for easier access, as well as flags.
|
||||
context.system = actorData.system;
|
||||
context.flags = actorData.flags;
|
||||
|
||||
this.#addSkillsToContext(context)
|
||||
this.#addAdvantagesToContext(context)
|
||||
this.#addAttributesToContext(context)
|
||||
this.#addEquipmentsToContext(context)
|
||||
await this.#addCombatStatistics(context)
|
||||
this.#addActionsToContext(context)
|
||||
return context;
|
||||
}
|
||||
|
||||
static getElementByName(collection, id) {
|
||||
|
|
@ -98,56 +107,140 @@ export class CharacterSheet extends ActorSheet {
|
|||
);
|
||||
}
|
||||
|
||||
#addAttributesToContext(context) {
|
||||
#cleanUpMerkmal(merkmale) {
|
||||
return merkmale.split(",").map((merkmal) => merkmal.trim())
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async getData() {
|
||||
const context = super.getData();
|
||||
|
||||
|
||||
// Use a safe clone of the actor data for further operations.
|
||||
const actorData = context.data;
|
||||
|
||||
// Add the actor's data to context.data for easier access, as well as flags.
|
||||
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 ?? [];
|
||||
|
||||
this.#addSkillsToContext(context)
|
||||
this.#addAdvantagesToContext(context)
|
||||
this.#addSpecialAbilitiesToContext(context)
|
||||
await this.#addAttributesToContext(context)
|
||||
this.#addEquipmentsToContext(context)
|
||||
await this.#addCombatStatistics(context)
|
||||
this.#addActionsToContext(context)
|
||||
this.#addSpellsToContext(context)
|
||||
this.#addLiturgiesToContext(context)
|
||||
return context;
|
||||
}
|
||||
|
||||
#addSpellsToContext(context) {
|
||||
const actorData = context.data;
|
||||
context.spells = [];
|
||||
Object.values(actorData.items).forEach((item, index) => {
|
||||
if (item.type === "Spell") {
|
||||
const eigenschaften = item.system.probe;
|
||||
const werte = [
|
||||
{name: eigenschaften[0], value: this.prepareEigenschaftRoll(actorData, eigenschaften[0])},
|
||||
{name: eigenschaften[1], value: this.prepareEigenschaftRoll(actorData, eigenschaften[1])},
|
||||
{name: eigenschaften[2], value: this.prepareEigenschaftRoll(actorData, eigenschaften[2])}
|
||||
]
|
||||
context.spells.push({
|
||||
id: item._id,
|
||||
name: item.name,
|
||||
zfw: item.system.zfw,
|
||||
hauszauber: item.system.hauszauber,
|
||||
merkmal: this.#cleanUpMerkmal(item.system.merkmal),
|
||||
rollEigenschaft1: werte[0].value,
|
||||
rollEigenschaft2: werte[1].value,
|
||||
rollEigenschaft3: werte[2].value,
|
||||
eigenschaft1: werte[0].name,
|
||||
eigenschaft2: werte[1].name,
|
||||
eigenschaft3: werte[2].name,
|
||||
})
|
||||
}
|
||||
})
|
||||
context.hasSpells = context.spells.length > 0;
|
||||
}
|
||||
|
||||
async #getModsOfAttribute(keyPath) {
|
||||
let returnValue = [];
|
||||
Array.from(this.object.appliedEffects).forEach(
|
||||
(e) =>
|
||||
e.changes.filter(c => c.key === keyPath).forEach(change => {
|
||||
returnValue.push({
|
||||
name: e.name,
|
||||
value: change.value > 0 ? "+" + change.value : "" + change.value,
|
||||
icon: e.icon,
|
||||
})
|
||||
}))
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
async #addAttributesToContext(context) {
|
||||
context.mods = {
|
||||
"mu": await this.#getModsOfAttribute('system.attribute.mu.mod'),
|
||||
"kl": await this.#getModsOfAttribute('system.attribute.kl.mod'),
|
||||
"in": await this.#getModsOfAttribute('system.attribute.in.mod'),
|
||||
"ch": await this.#getModsOfAttribute('system.attribute.ch.mod'),
|
||||
"ff": await this.#getModsOfAttribute('system.attribute.ff.mod'),
|
||||
"ge": await this.#getModsOfAttribute('system.attribute.ge.mod'),
|
||||
"ko": await this.#getModsOfAttribute('system.attribute.ko.mod'),
|
||||
"kk": await this.#getModsOfAttribute('system.attribute.kk.mod')
|
||||
}
|
||||
context.attributes = [
|
||||
{
|
||||
eigenschaft: "mu",
|
||||
name: "MU",
|
||||
tooltip: "Mut",
|
||||
wert: actorData.system.attribute.mu.aktuell ?? 0,
|
||||
wert: (context.derived.attribute.mu.aktuell + context.derived.attribute.mu.mod) ?? 0,
|
||||
},
|
||||
{
|
||||
eigenschaft: "kl",
|
||||
name: "KL",
|
||||
tooltip: "Klugheit",
|
||||
wert: actorData.system.attribute.kl.aktuell ?? 0,
|
||||
wert: (context.derived.attribute.kl.aktuell + context.derived.attribute.kl.mod) ?? 0,
|
||||
},
|
||||
{
|
||||
eigenschaft: "in",
|
||||
name: "IN",
|
||||
tooltip: "Intuition",
|
||||
wert: actorData.system.attribute.in.aktuell ?? 0,
|
||||
wert: (context.derived.attribute.in.aktuell + context.derived.attribute.in.mod) ?? 0,
|
||||
},
|
||||
{
|
||||
eigenschaft: "ch",
|
||||
name: "CH",
|
||||
tooltip: "Charisma",
|
||||
wert: actorData.system.attribute.ch.aktuell ?? 0,
|
||||
wert: (context.derived.attribute.ch.aktuell + context.derived.attribute.ch.mod) ?? 0,
|
||||
},
|
||||
{
|
||||
eigenschaft: "ff",
|
||||
name: "FF",
|
||||
tooltip: "Fingerfertigkeit",
|
||||
wert: actorData.system.attribute.ff.aktuell ?? 0,
|
||||
wert: (context.derived.attribute.ff.aktuell + context.derived.attribute.ff.mod) ?? 0,
|
||||
},
|
||||
{
|
||||
eigenschaft: "ge",
|
||||
name: "GE",
|
||||
tooltip: "Geschicklichkeit",
|
||||
wert: actorData.system.attribute.ge.aktuell ?? 0,
|
||||
wert: (context.derived.attribute.ge.aktuell + context.derived.attribute.ge.mod) ?? 0,
|
||||
},
|
||||
{
|
||||
eigenschaft: "ko",
|
||||
name: "KO",
|
||||
tooltip: "Konstitution",
|
||||
wert: actorData.system.attribute.ko.aktuell ?? 0,
|
||||
wert: (context.derived.attribute.ko.aktuell + context.derived.attribute.ko.mod) ?? 0,
|
||||
},
|
||||
{
|
||||
eigenschaft: "kk",
|
||||
name: "KK",
|
||||
tooltip: "Körperkraft",
|
||||
wert: actorData.system.attribute.kk.aktuell ?? 0,
|
||||
wert: (context.derived.attribute.kk.aktuell + context.derived.attribute.kk.mod) ?? 0,
|
||||
},
|
||||
|
||||
];
|
||||
|
|
@ -171,12 +264,22 @@ export class CharacterSheet extends ActorSheet {
|
|||
);
|
||||
}
|
||||
|
||||
#findEquipmentOnSlot(slot, setNumber) {
|
||||
return this.object.items.get(this.object.system.heldenausruestung[setNumber][slot])
|
||||
#addSpecialAbilitiesToContext(context) {
|
||||
context.specialAbilities = [];
|
||||
const actorData = context.data;
|
||||
Object.values(actorData.items).forEach((item) => {
|
||||
if (item.type === "SpecialAbility") {
|
||||
context.specialAbilities.push({
|
||||
id: item._id,
|
||||
name: item.name,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#findTalentsOfEquipment(equipment) {
|
||||
|
||||
#findEquipmentOnSlot(slot, setNumber) {
|
||||
return this.object.items.get(this.object.system.heldenausruestung[setNumber]?.[slot])
|
||||
}
|
||||
|
||||
#addActionsToContext(context) {
|
||||
|
|
@ -184,14 +287,16 @@ export class CharacterSheet extends ActorSheet {
|
|||
context.actions = am.evaluate()
|
||||
}
|
||||
|
||||
#isWorn(itemId, setId) {
|
||||
#isWorn(itemId) {
|
||||
|
||||
const slots = PlayerCharacterDataModel.getSlots()
|
||||
const set = this.object.system.heldenausruestung[setId]
|
||||
for (const slot of slots) {
|
||||
const equipmentSlotId = set[slot]
|
||||
if (equipmentSlotId === itemId) {
|
||||
return slot
|
||||
const set = this.object.system.heldenausruestung[this.object.system.setEquipped]
|
||||
if (set) {
|
||||
for (const slot of slots) {
|
||||
const equipmentSlotId = set[slot]
|
||||
if (equipmentSlotId === itemId) {
|
||||
return slot
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -207,13 +312,15 @@ export class CharacterSheet extends ActorSheet {
|
|||
|
||||
context.aupper = Math.min((context.actor.system.aup.aktuell / context.actor.system.aup.max) * 100, 100);
|
||||
context.lepper = Math.min((context.actor.system.lep.aktuell / context.actor.system.lep.max) * 100, 100);
|
||||
context.keper = Math.min((context.actor.system.kap.aktuell / context.actor.system.kap.max) * 100, 100);
|
||||
context.aspper = Math.min((context.actor.system.asp.aktuell / context.actor.system.asp.max) * 100, 100);
|
||||
context.lepcurrent = context.actor.system.lep.aktuell ?? 0
|
||||
|
||||
context.aupcurrent = context.actor.system.aup.aktuell ?? 0
|
||||
|
||||
const fernkampf = this.#findEquipmentOnSlot("fernkampf", 0)
|
||||
const links = this.#findEquipmentOnSlot("links", 0)
|
||||
const rechts = this.#findEquipmentOnSlot("rechts", 0)
|
||||
const fernkampf = this.#findEquipmentOnSlot("fernkampf", context.actor.system.setEquipped)
|
||||
const links = this.#findEquipmentOnSlot("links", context.actor.system.setEquipped)
|
||||
const rechts = this.#findEquipmentOnSlot("rechts", context.actor.system.setEquipped)
|
||||
context.attacks = [];
|
||||
|
||||
if (fernkampf) {
|
||||
|
|
@ -269,7 +376,7 @@ export class CharacterSheet extends ActorSheet {
|
|||
}
|
||||
|
||||
prepareEigenschaftRoll(actorData, name) {
|
||||
if (name) {
|
||||
if (name && name !== "*") {
|
||||
return actorData.system.attribute[name.toLowerCase()].aktuell
|
||||
} else {
|
||||
return 0
|
||||
|
|
@ -282,16 +389,24 @@ export class CharacterSheet extends ActorSheet {
|
|||
context.carryingweight = 0;
|
||||
Object.values(actorData.items).forEach((item, index) => {
|
||||
if (item.type === "Equipment") {
|
||||
|
||||
// worn items are halved weight
|
||||
|
||||
let effectiveWeight = item.system.weight ?? 0
|
||||
if (this.#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 ?? 0,
|
||||
worn: this.#isWorn(item._id, 0)
|
||||
weight: item.system.weight,
|
||||
worn: this.#isWorn(item._id)
|
||||
})
|
||||
context.carryingweight += item.system.quantity * item.system.weight;
|
||||
context.carryingweight += item.system.quantity * effectiveWeight;
|
||||
}
|
||||
})
|
||||
context.maxcarryingcapacity = actorData.system.attribute.kk.aktuell
|
||||
|
|
@ -477,22 +592,23 @@ export class CharacterSheet extends ActorSheet {
|
|||
}
|
||||
}
|
||||
|
||||
#getEquipmentset(setId) {
|
||||
const equipmentSet = this.object.system.heldenausruestung[setId]
|
||||
#mapAllSets() {
|
||||
const updateObject = {}
|
||||
// TODO: there's got to be a better angle!
|
||||
updateObject[`system.heldenausruestung.${setId}.links`] = equipmentSet.links;
|
||||
updateObject[`system.heldenausruestung.${setId}.rechts`] = equipmentSet.rechts;
|
||||
updateObject[`system.heldenausruestung.${setId}.brust`] = equipmentSet.brust;
|
||||
updateObject[`system.heldenausruestung.${setId}.bauch`] = equipmentSet.bauch;
|
||||
updateObject[`system.heldenausruestung.${setId}.ruecken`] = equipmentSet.ruecken;
|
||||
updateObject[`system.heldenausruestung.${setId}.kopf`] = equipmentSet.kopf;
|
||||
updateObject[`system.heldenausruestung.${setId}.fernkampf`] = equipmentSet.fernkampf;
|
||||
updateObject[`system.heldenausruestung.${setId}.munition`] = equipmentSet.munition;
|
||||
updateObject[`system.heldenausruestung.${setId}.armlinks`] = equipmentSet.armlinks;
|
||||
updateObject[`system.heldenausruestung.${setId}.armrechts`] = equipmentSet.armrechts;
|
||||
updateObject[`system.heldenausruestung.${setId}.beinlinks`] = equipmentSet.beinlinks;
|
||||
updateObject[`system.heldenausruestung.${setId}.beinrechts`] = equipmentSet.beinrechts;
|
||||
Array.from(this.object.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;
|
||||
}
|
||||
|
||||
|
|
@ -528,13 +644,137 @@ export class CharacterSheet extends ActorSheet {
|
|||
|
||||
}
|
||||
|
||||
#addLiturgiesToContext(context) {
|
||||
const actorData = context.data;
|
||||
context.liturgies = [];
|
||||
context.blessings = [];
|
||||
|
||||
Object.values(actorData.items).forEach((item, index) => {
|
||||
if (item.type === "Blessing") {
|
||||
context.blessings.push({
|
||||
deity: item.system.gottheit,
|
||||
value: item.system.wert
|
||||
})
|
||||
}
|
||||
})
|
||||
Object.values(actorData.items).forEach((item, index) => {
|
||||
if (item.type === "Liturgy") {
|
||||
|
||||
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 + 1;
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
// clean up counter
|
||||
Object.values(context.liturgies).forEach((litObject) => {
|
||||
|
||||
if (litObject.O.length === 0) litObject.countO = false;
|
||||
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;
|
||||
}
|
||||
|
||||
#handleDroppedSkill(actor, skill) {
|
||||
const array = Array.from(actor.items);
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
if (array[i].name === skill.name) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async #handleDroppedActiveEffect(actor, activeEffect) {
|
||||
const array = Array.from(actor.items);
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
if (array[i].name === activeEffect.name) {
|
||||
// replace active effect
|
||||
actor.deleteEmbeddedDocuments('Item', [array[i].id]).then(() => {
|
||||
console.log("await")
|
||||
})
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#handleDroppedAdvantage(actor, advantage) {
|
||||
const array = Array.from(actor.items);
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
if (array[i].name === advantage.name) { // TODO: adjust for uniqueness
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
const tabs = new Tabs({
|
||||
navSelector: ".paperdoll-tabs.tabs",
|
||||
contentSelector: ".sheet-body.paperdoll-sets",
|
||||
initial: "set1"
|
||||
initial: "set" + (this.object.system.setEquipped + 1)
|
||||
});
|
||||
tabs.bind(html[0]);
|
||||
|
||||
|
|
@ -542,6 +782,12 @@ export class CharacterSheet extends ActorSheet {
|
|||
this._onAttributeRoll(evt);
|
||||
});
|
||||
|
||||
html.on('click', '[data-operation="switchSet"]', (evt) => {
|
||||
const {id} = evt.currentTarget.dataset;
|
||||
console.log(id);
|
||||
this.object.update({"system.setEquipped": id})
|
||||
})
|
||||
|
||||
html.on('click', '.talent.rollable', (evt) => {
|
||||
this._onTalentRoll(evt);
|
||||
});
|
||||
|
|
@ -550,21 +796,32 @@ export class CharacterSheet extends ActorSheet {
|
|||
this._onRoll(evt);
|
||||
});
|
||||
|
||||
// TODO: merge into click.clickable handler
|
||||
html.on('click', '.talent .name', (evt) => {
|
||||
this.openEmbeddedDocument(evt.target.dataset.id);
|
||||
evt.stopPropagation();
|
||||
})
|
||||
|
||||
// TODO: merge into click.clickable handler
|
||||
html.on('click', '.advantage .name', (evt) => {
|
||||
this.openEmbeddedDocument(evt.target.dataset.id);
|
||||
evt.stopPropagation();
|
||||
})
|
||||
|
||||
// TODO: merge into click.clickable handler
|
||||
html.on('click', '.equipment', (evt) => {
|
||||
this.openEmbeddedDocument(evt.target.parentElement.dataset.id);
|
||||
evt.stopPropagation();
|
||||
})
|
||||
|
||||
html.on('click', '.clickable', async (evt) => {
|
||||
const {id, operation} = evt.currentTarget.dataset;
|
||||
if (operation === "openActorSheet") {
|
||||
this.openEmbeddedDocument(id);
|
||||
evt.stopPropagation();
|
||||
}
|
||||
})
|
||||
|
||||
html.on('dragstart', '.equipment', (evt) => {
|
||||
evt.originalEvent.dataTransfer.setData("application/json", JSON.stringify({
|
||||
documentId: evt.currentTarget.dataset.id
|
||||
|
|
@ -579,7 +836,8 @@ export class CharacterSheet extends ActorSheet {
|
|||
|
||||
if (actor === this.object._id && documentId) { // managing equipped items
|
||||
//const slot = this.#isWorn(documentId, setId)
|
||||
const updateObject = this.#getEquipmentset(setId)
|
||||
//const updateObject = await this.#getEquipmentset(Number(setId))
|
||||
const updateObject = this.#mapAllSets()
|
||||
updateObject[`system.heldenausruestung.${setId}.${target}`] = documentId;
|
||||
console.log(updateObject);
|
||||
|
||||
|
|
@ -640,7 +898,7 @@ export class CharacterSheet extends ActorSheet {
|
|||
callback: (event) => {
|
||||
const {setId, target, actor} = event[0].dataset
|
||||
|
||||
const updateObject = this.#getEquipmentset(setId)
|
||||
const updateObject = this.#mapAllSets()
|
||||
updateObject[`system.heldenausruestung.${setId}.${target}`] = null;
|
||||
|
||||
this.object.update(updateObject);
|
||||
|
|
@ -649,57 +907,86 @@ export class CharacterSheet extends ActorSheet {
|
|||
}
|
||||
]);
|
||||
|
||||
}
|
||||
html.on('click', '.liturgy.rollable', async (evt) => {
|
||||
|
||||
#handleDroppedSkill(actor, skill) {
|
||||
const array = Array.from(actor.items);
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
if (array[i].name === skill.name) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
evt.stopPropagation();
|
||||
|
||||
#handleDroppedAdvantage(actor, advantage) {
|
||||
const array = Array.from(actor.items);
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
if (array[i].name === advantage.name) { // TODO: adjust for uniqueness
|
||||
return false;
|
||||
const {id, rank, lkp, deity} = evt.currentTarget.dataset;
|
||||
const document = await this.object.items.get(id)
|
||||
|
||||
const data = {};
|
||||
|
||||
data.rank = rank;
|
||||
data.lkp = lkp;
|
||||
data.deity = deity;
|
||||
data.variations = [];
|
||||
const ranks = LiturgyData.ranks
|
||||
ranks.forEach(rank => {
|
||||
if (document.system.auswirkung[rank]) {
|
||||
data.variations.push({
|
||||
rank,
|
||||
effect: document.system.auswirkung[rank]
|
||||
})
|
||||
}
|
||||
})
|
||||
data.mods = [];
|
||||
|
||||
const htmlContent = await renderTemplate('systems/DSA_4-1/templates/dialog/modify-liturgy.hbs', data);
|
||||
|
||||
const dialogData = {
|
||||
title: document.name,
|
||||
content: htmlContent,
|
||||
data: {},
|
||||
buttons: {
|
||||
submit: {
|
||||
label: "Wirken",
|
||||
icon: '<i class="fas fa-die"></i>',
|
||||
callback: (html) => {
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
dialogData.render = new ModifyLiturgy(data).handleRender
|
||||
|
||||
const dialog = new Dialog(dialogData, {
|
||||
classes: ['dsa41', 'dialog', 'liturgy'],
|
||||
height: 480
|
||||
})
|
||||
|
||||
dialog.render(true);
|
||||
|
||||
return false;
|
||||
})
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#handleDroppedEquipment(actor, equipment) {
|
||||
const array = Array.from(actor.items);
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
if (array[i].name === equipment.name) { // TODO: adjust item quantity if item is the same
|
||||
console.log(equipment);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static onDroppedData(actor, characterSheet, data) {
|
||||
const uuid = foundry.utils.parseUuid(data.uuid);
|
||||
const collection = uuid.collection.index ?? uuid.collection;
|
||||
const document = CharacterSheet.getElementByName(collection, uuid.id);
|
||||
const {
|
||||
name,
|
||||
type
|
||||
} = document
|
||||
console.log(name, type)
|
||||
switch (type) {
|
||||
case "Skill":
|
||||
return characterSheet.#handleDroppedSkill(actor, document); // on false cancel this whole operation
|
||||
case "Advantage":
|
||||
return characterSheet.#handleDroppedAdvantage(actor, document);
|
||||
case "Equipment":
|
||||
return characterSheet.#handleDroppedEquipment(actor, document);
|
||||
|
||||
default:
|
||||
#handleDroppedLiturgy(actor, liturgy) {
|
||||
const array = Array.from(actor.items);
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
if (array[i].name === liturgy.name) { // TODO: allow multiple miracles with the same name
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#handleDroppedSpecialAbility(actor, specialAbility) {
|
||||
const array = Array.from(actor.items);
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
if (array[i].name === specialAbility.name) { // TODO: allow multiple miracles with the same name
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,10 +72,10 @@ export class CreatureSheet extends foundry.appv1.sheets.ActorSheet {
|
|||
})
|
||||
|
||||
html.on('click', '.editor .add-attack', async (evt) => {
|
||||
const name = evt.target.parentElement.querySelector('#attack_name').value
|
||||
const at = evt.target.parentElement.querySelector('#attack_at').value
|
||||
const pa = evt.target.parentElement.querySelector('#attack_pa').value
|
||||
const tp = evt.target.parentElement.querySelector('#attack_tp').value
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -15,6 +15,54 @@ export class GroupSheet extends ActorSheet {
|
|||
});
|
||||
}
|
||||
|
||||
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
|
||||
const settings = {...group.system.settings}
|
||||
character.items.filter((i) => i.type === "Advantage").forEach((advantage) => {
|
||||
settings[this.#stringToKeyFieldName(advantage.name)] = false
|
||||
})
|
||||
character.items.filter((i) => i.type === "Skill").forEach((skill) => {
|
||||
settings[this.#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`)
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
#stringToKeyFieldName(s) {
|
||||
return s.replace(/[ \[\]:]/g, "_").toLowerCase()
|
||||
}
|
||||
|
||||
/** @override */
|
||||
get template() {
|
||||
return `systems/DSA_4-1/templates/actor/group-sheet.hbs`;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async getData() {
|
||||
const context = super.getData();
|
||||
|
|
@ -25,8 +73,11 @@ export class GroupSheet extends ActorSheet {
|
|||
// Add the actor's data to context.data for easier access, as well as flags.
|
||||
context.system = groupData.system;
|
||||
context.flags = groupData.flags;
|
||||
context.characters = []
|
||||
|
||||
context.characters = [];
|
||||
context.fields = [];
|
||||
|
||||
const hiddenFields = Object.entries(groupData.system.settings).filter(([key, value]) => value === true).map(([key, value]) => key)
|
||||
|
||||
for (const characterId of groupData.system.characters) {
|
||||
const character = await game.actors.get(characterId)
|
||||
|
|
@ -45,14 +96,14 @@ export class GroupSheet extends ActorSheet {
|
|||
{name: "KO", value: character.system.attribute.ko.aktuell},
|
||||
{name: "KK", value: character.system.attribute.kk.aktuell},
|
||||
],
|
||||
advantages: character.items.filter((i) => i.type === "Advantage").map((advantage) => {
|
||||
advantages: character.items.filter((i) => i.type === "Advantage").filter((i) => hiddenFields.includes(this.#stringToKeyFieldName(i.name))).map((advantage) => {
|
||||
return {
|
||||
name: advantage.name,
|
||||
id: advantage._id,
|
||||
value: advantage.system.value,
|
||||
}
|
||||
}),
|
||||
skills: character.items.filter((i) => i.type === "Skill").map((skill) => {
|
||||
skills: character.items.filter((i) => i.type === "Skill").filter((i) => hiddenFields.includes(this.#stringToKeyFieldName(i.name))).map((skill) => {
|
||||
return {
|
||||
name: skill.name,
|
||||
taw: skill.system.taw,
|
||||
|
|
@ -66,7 +117,6 @@ export class GroupSheet extends ActorSheet {
|
|||
)
|
||||
}
|
||||
|
||||
|
||||
context.equipments = [];
|
||||
const actorData = context.data;
|
||||
Object.values(actorData.items).forEach((item, index) => {
|
||||
|
|
@ -84,41 +134,6 @@ export class GroupSheet extends ActorSheet {
|
|||
return await context;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
get template() {
|
||||
return `systems/DSA_4-1/templates/actor/group-sheet.hbs`;
|
||||
}
|
||||
|
||||
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
|
||||
await group.update({
|
||||
system: {
|
||||
characters: [
|
||||
...group.system.characters,
|
||||
character._id
|
||||
]
|
||||
}
|
||||
})
|
||||
ui.notifications.info(`${character.name} ist der Heldengruppe ${group.name} beigetreten`)
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
openEmbeddedDocument(documentId) {
|
||||
this.object.items.get(documentId).sheet.render(true)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
export class LiturgySheet extends ItemSheet {
|
||||
/**@override */
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ['dsa41', 'sheet', 'item', 'liturgy'],
|
||||
width: 520,
|
||||
height: 480,
|
||||
tabs: [
|
||||
{
|
||||
navSelector: '.sheet-tabs',
|
||||
contentSelector: '.sheet-body',
|
||||
initial: 'description',
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
/** @override */
|
||||
get template() {
|
||||
return `systems/DSA_4-1/templates/item/item-liturgy-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 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) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
export class SpecialAbilitySheet extends ItemSheet {
|
||||
/**@override */
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ['dsa41', 'sheet', 'item', 'specialability'],
|
||||
width: 520,
|
||||
height: 480,
|
||||
tabs: [
|
||||
{
|
||||
navSelector: '.sheet-tabs',
|
||||
contentSelector: '.sheet-body',
|
||||
initial: 'description',
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
/** @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) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -34,7 +34,13 @@ export class VornachteilSheet extends ItemSheet {
|
|||
// Add the actor's data to context.data for easier access, as well as flags.
|
||||
context.system = advantageData.system;
|
||||
context.flags = advantageData.flags;
|
||||
context.json = JSON.stringify(advantageData.system, null, 4);
|
||||
|
||||
context.choices = {}
|
||||
context.system.auswahl.forEach(a => {
|
||||
context.choices[a] = a
|
||||
})
|
||||
context.hasChoices = context.system.auswahl.length > 0;
|
||||
context.hasModality = context.system.value == null
|
||||
|
||||
return context;
|
||||
}
|
||||
|
|
@ -43,7 +49,9 @@ export class VornachteilSheet extends ItemSheet {
|
|||
super.activateListeners(html);
|
||||
|
||||
// Everything below here is only needed if the sheet is editable
|
||||
if (!this.isEditable) return;
|
||||
if (!this.isEditable) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
import {LiturgyData} from "../data/miracle/liturgydata.mjs";
|
||||
import {BlessingDataModel} from "../data/blessing.mjs";
|
||||
import {Blessing} from "../documents/blessing.mjs";
|
||||
|
||||
let months = [
|
||||
"Praios",
|
||||
"Rondra",
|
||||
|
|
@ -71,7 +75,7 @@ function getJsonFromXML(dom) {
|
|||
}
|
||||
|
||||
async function addSkillFromCompendiumByNameToActor(talentName, taw, actor) {
|
||||
const compendiumOfSkills = game.packs.get('DSA_4-1.talente-brw');
|
||||
const compendiumOfSkills = game.packs.get('DSA_4-1.talente');
|
||||
const talentId = compendiumOfSkills.index.find(skill => skill.name === talentName)
|
||||
if (talentId) {
|
||||
|
||||
|
|
@ -102,6 +106,40 @@ async function addAdvantageFromCompendiumByNameToActor(advantageName, advantageV
|
|||
}
|
||||
}
|
||||
|
||||
async function addSpellsFromCompendiumByNameToActor(spellName, zfw, representation, hauszauber, actor) {
|
||||
const compendiumOfSpells = game.packs.get('DSA_4-1.spells');
|
||||
const SCREAMING_NAME = spellName.toUpperCase()
|
||||
const spellId = compendiumOfSpells.index.find(spell => spell.name === SCREAMING_NAME)
|
||||
if (spellId) {
|
||||
|
||||
const spell = await compendiumOfSpells.getDocument(spellId._id);
|
||||
|
||||
try {
|
||||
const embeddedDocument = (await actor.createEmbeddedDocuments('Item', [spell]))[0]
|
||||
embeddedDocument.update({system: {zfw: zfw, hauszauber: hauszauber, repräsentation: representation}});
|
||||
} catch (error) {
|
||||
console.error(`${spell} not found in items`, error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function addLiturgiesFromCompendiumByNameToActor(liturgyName, actor) {
|
||||
const compendiumOfLiturgies = game.packs.get('DSA_4-1.liturgien');
|
||||
const liturgyId = compendiumOfLiturgies.index.find(liturgy => {
|
||||
return liturgy.name === LiturgyData.lookupAlias(liturgyName.split(" (")[0])
|
||||
})
|
||||
if (liturgyId) {
|
||||
|
||||
const liturgy = await compendiumOfLiturgies.getDocument(liturgyId._id);
|
||||
|
||||
try {
|
||||
await actor.createEmbeddedDocuments('Item', [liturgy])
|
||||
} catch (error) {
|
||||
console.error(`${liturgy} not found in items`, error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the text content of a file
|
||||
* @param file the file with the desired content
|
||||
|
|
@ -136,7 +174,25 @@ function calculateBirthdate(json) {
|
|||
function mapSkills(actor, held) {
|
||||
for (let talent in held.talentliste.talent) {
|
||||
talent = held.talentliste.talent[talent]
|
||||
addSkillFromCompendiumByNameToActor(talent.name, talent.value, actor)
|
||||
|
||||
// hook liturgy
|
||||
if (talent.name.startsWith("Liturgiekenntnis")) {
|
||||
|
||||
actor.createEmbeddedDocuments('Item', [
|
||||
new Blessing({
|
||||
name: talent.name,
|
||||
type: "Blessing",
|
||||
system: {
|
||||
gottheit: new RegExp("\\((.+)\\)").exec(talent.name)[1],
|
||||
wert: talent.value
|
||||
}
|
||||
})
|
||||
])
|
||||
|
||||
} else {
|
||||
// proceed
|
||||
addSkillFromCompendiumByNameToActor(talent.name, talent.value, actor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -147,6 +203,20 @@ function mapAdvantages(actor, held) {
|
|||
}
|
||||
}
|
||||
|
||||
function mapSpells(actor, held) {
|
||||
for (let spell in held.zauberliste.zauber) {
|
||||
spell = held.zauberliste.zauber[spell]
|
||||
addSpellsFromCompendiumByNameToActor(spell.name, spell.value, spell.repraesentation, spell.hauszauber === "true", actor)
|
||||
}
|
||||
}
|
||||
|
||||
function mapMiracles(actor, liturgies) {
|
||||
for (let liturgy in liturgies) {
|
||||
liturgy = liturgies[liturgy]
|
||||
addLiturgiesFromCompendiumByNameToActor(liturgy.name, actor)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* parses a json into a fitting character-json
|
||||
* @param rawJson the json parsed from the Helden-Software XML
|
||||
|
|
@ -181,16 +251,14 @@ function mapRawJson(actor, rawJson) {
|
|||
held.basis.rasse.aussehen.aussehentext0,
|
||||
held.basis.rasse.aussehen.aussehentext1,
|
||||
held.basis.rasse.aussehen.aussehentext2,
|
||||
held.basis.rasse.aussehen.aussehentext3,
|
||||
]
|
||||
held.basis.rasse.aussehen.aussehentext3].join('\n')
|
||||
json.meta.familie = [
|
||||
held.basis.rasse.aussehen.familietext0,
|
||||
held.basis.rasse.aussehen.familietext1,
|
||||
held.basis.rasse.aussehen.familietext2,
|
||||
held.basis.rasse.aussehen.familietext3,
|
||||
held.basis.rasse.aussehen.familietext4,
|
||||
held.basis.rasse.aussehen.familietext5,
|
||||
]
|
||||
held.basis.rasse.aussehen.familietext5].join('\n')
|
||||
json.meta.titel = held.basis.rasse.aussehen.titel
|
||||
json.meta.stand = held.basis.rasse.aussehen.stand
|
||||
let attributes = held.eigenschaften.eigenschaft
|
||||
|
|
@ -266,19 +334,9 @@ function mapRawJson(actor, rawJson) {
|
|||
json.liturgien = liturgies
|
||||
|
||||
mapSkills(actor, held)
|
||||
let spells = []
|
||||
/*for (let spell in held.zauberliste.zauber) {
|
||||
spell = held.zauberliste.zauber[spell]
|
||||
spells.push({
|
||||
name: spell.name,
|
||||
rep: spell.repraesentation,
|
||||
hauszauber: spell.hauszauber === "true",
|
||||
zfw: spell.value,
|
||||
anmerkungen: spell.zauberkommentar,
|
||||
komplexitaet: spell.k,
|
||||
})
|
||||
}*/
|
||||
json.zauber = spells
|
||||
mapSpells(actor, held)
|
||||
mapMiracles(actor, liturgies)
|
||||
|
||||
let combatValues = []
|
||||
for (let combatValue in held.kampf.kampfwerte) {
|
||||
combatValue = held.kampf.kampfwerte[combatValue]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "Argelions bannende Hand",
|
||||
"grad": 5,
|
||||
"herkunft": [
|
||||
{
|
||||
"name": "Hesinde",
|
||||
"grad": 5
|
||||
},
|
||||
{
|
||||
"name": "Praios",
|
||||
"grad": 5
|
||||
}
|
||||
],
|
||||
"reichweite": "Sicht",
|
||||
"ziel": "Zauber (auf Person, Objekt oder Zone)",
|
||||
"zauberdauer": "1 Spielrunde (Gebet)",
|
||||
"wirkungsdauer": "LkP* Stunden, eventuell augenblicklich",
|
||||
"auswirkung": {
|
||||
"V": "Diese Liturgie schwächt die Wirkung von Zaubern und Ritualen, die auf einem Objekt, auf einer Person oder (bei Flächenzaubern) auf einer Zone liegen, und kann sie gar völlig aufheben. Die LkP*+15 der Geweihten werden von den ZfP* des Zaubers oder Rituals abgezogen und so die Wirkung vermindert; fällt die Wirkung unter 0 ZfP*, ist die Magie dauerhaft gebannt; fällt die Wirkung des Zaubers genau auf 0 ZfP*, entspricht sie wie gehabt der Wirkung von 1 ZfP*."
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "Auge des Mondes",
|
||||
"grad": 2,
|
||||
"herkunft": [
|
||||
{
|
||||
"name": "Phex",
|
||||
"grad": 2
|
||||
}
|
||||
],
|
||||
"reichweite": "Selbst",
|
||||
"ziel": "Geweihter",
|
||||
"wirkungsdauer": "LkP* Stunden, maximal bis zum nächsten Sonnenaufgang",
|
||||
"auswirkung": {
|
||||
"II": "Der Geweihte ignoriert Dunkelheit (und daraus resultierende Abzüge) vollständig; er sieht, als wäre es helllichter Tag."
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
{
|
||||
"name": "Exkommunikation",
|
||||
"grad": 3,
|
||||
"herkunft": [
|
||||
{
|
||||
"name": "Praios",
|
||||
"grad": 3
|
||||
},
|
||||
{
|
||||
"name": "Rondra",
|
||||
"grad": 3
|
||||
},
|
||||
{
|
||||
"name": "Efferd",
|
||||
"grad": 3
|
||||
},
|
||||
{
|
||||
"name": "Travia",
|
||||
"grad": 3
|
||||
},
|
||||
{
|
||||
"name": "Boron",
|
||||
"grad": 3
|
||||
},
|
||||
{
|
||||
"name": "Hesinde",
|
||||
"grad": 3
|
||||
},
|
||||
{
|
||||
"name": "Firun",
|
||||
"grad": 3
|
||||
},
|
||||
{
|
||||
"name": "Tsa",
|
||||
"grad": 3
|
||||
},
|
||||
{
|
||||
"name": "Phex",
|
||||
"grad": 3
|
||||
},
|
||||
{
|
||||
"name": "Peraine",
|
||||
"grad": 3
|
||||
},
|
||||
{
|
||||
"name": "Ingrerimm",
|
||||
"grad": 3
|
||||
},
|
||||
{
|
||||
"name": "Rahja",
|
||||
"grad": 3
|
||||
},
|
||||
{
|
||||
"name": "Angrosch",
|
||||
"grad": 3
|
||||
},
|
||||
{
|
||||
"name": "H'Ranga",
|
||||
"grad": 3
|
||||
}
|
||||
],
|
||||
"reichweite": "Sicht",
|
||||
"ziel": "1 Person",
|
||||
"zauberdauer": "Andacht",
|
||||
"wirkungsdauer": "permanent",
|
||||
"auswirkung": {
|
||||
"III": "Dieses Ritual schließt eine Person rechtlich aus der Zwölfgöttlichen Gemeinschaft aus (üblicherweise jemanden, der sich gegen die göttlichen Gebote vergangen hat) und zeichnet sie als Frevler, so dass sie keinen Zugang zu den Paradiesen der Zwölfe erhalten kann, wenn sie vor Tilgung des Makels stirbt. Zudem profitieren Frevlerin geringerem Maß von segnenden Liturgien. Wenn die vom Exkommunizierenden verhängte Bußqueste vollbracht ist, endet der Ausschluss von kirchlichen Segnungen automatisch.",
|
||||
"IV": "Exkommunizierte Geweihte verlieren sämtliche Karmaenergie und können natürlich auch keine durch Gebete o.ä. wieder gewinnen; ihr geistlicher Stand ruht, bis sie Buße getan haben.",
|
||||
"V": "Eine nur <i>Kirchenoberhäuptern</i> bekannte Variante der EXKOMMUNIKATION nimmt auch die Weihen dauerhaft von einem Priester."
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
{
|
||||
"name": "Handwerkssegen",
|
||||
"alias": [
|
||||
"Cereborns Handreichung (Handwerkssegen)",
|
||||
"Hauch der Leidenschaft (Handwerkssegen)"
|
||||
],
|
||||
"grad": 1,
|
||||
"herkunft": [
|
||||
{
|
||||
"name": "Praios",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rondra",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Efferd",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Travia",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Boron",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Hesinde",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Firun",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Tsa",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Phex",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Peraine",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Ingrerimm",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rahja",
|
||||
"grad": 1
|
||||
}
|
||||
],
|
||||
"reichweite": "Berührung",
|
||||
"ziel": "1 Person",
|
||||
"zauberdauer": "1 Spielrunde (Gebet)",
|
||||
"wirkungsdauer": "bis zum Ende der Probe, maximal LkP* Tage",
|
||||
"auswirkung": {
|
||||
"I": "Mit dieser Liturgie erfährt eine Person durch den Geweihten eine göttliche Inspiration in einem Talent, das für den Geweihten ein Mirakel+ Talent ist. Der TaW der inspirierten Person steigt für eine Probe um LkP*/2+5 Punkte. Solcherart geschaffene Werkstücke können bei vielen TaP* der Talentprobe nach Maßgabe des Meisters entweder besonders kunstfertig oder aber besonders robust sein, was beim Bau von Behelfsbrücken oder dergleichen wichtig sein kann."
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
{
|
||||
"name": "Heiliger Befehl",
|
||||
"alias": [],
|
||||
"grad": 2,
|
||||
"herkunft": [
|
||||
{
|
||||
"name": "Praios",
|
||||
"grad": 2
|
||||
},
|
||||
{
|
||||
"name": "Rondra",
|
||||
"grad": 2
|
||||
},
|
||||
{
|
||||
"name": "Efferd",
|
||||
"grad": 2
|
||||
},
|
||||
{
|
||||
"name": "Travia",
|
||||
"grad": 2
|
||||
},
|
||||
{
|
||||
"name": "Boron",
|
||||
"grad": 2
|
||||
},
|
||||
{
|
||||
"name": "Hesinde",
|
||||
"grad": 2
|
||||
},
|
||||
{
|
||||
"name": "Firun",
|
||||
"grad": 2
|
||||
},
|
||||
{
|
||||
"name": "Tsa",
|
||||
"grad": 2
|
||||
},
|
||||
{
|
||||
"name": "Phex",
|
||||
"grad": 2
|
||||
},
|
||||
{
|
||||
"name": "Peraine",
|
||||
"grad": 2
|
||||
},
|
||||
{
|
||||
"name": "Ingrerimm",
|
||||
"grad": 2
|
||||
},
|
||||
{
|
||||
"name": "Rahja",
|
||||
"grad": 2
|
||||
}
|
||||
],
|
||||
"reichweite": "Sicht",
|
||||
"ziel": "1 Person",
|
||||
"zauberdauer": "10 Aktionen (Stoßgebet)",
|
||||
"wirkungsdauer": "bis der Befehl ausgeführt wurde, längstens LkP* Tage",
|
||||
"auswirkung": {
|
||||
"II": "Die Stimme des Geweihten wird laut und auch auf weitere Entfernung hörbar. Die angesprochene Person kann sich gegen einen so gegebenen Befehl, der dem Wesen der Gottheit entsprechen muss, nur mit einer Selbstbeherrschungs-Probe zur Wehr setzen, die um LkP*/2+5 Punkte erschwert ist, ansonsten befolgt sie den Befehl."
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
"name": "Initiation",
|
||||
"alias": [],
|
||||
"grad": 2,
|
||||
"primärHerkunft": "Praios",
|
||||
"herkunft": [
|
||||
{
|
||||
"name": "Praios",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rondra",
|
||||
"grad": 2
|
||||
},
|
||||
{
|
||||
"name": "Efferd",
|
||||
"grad": 2
|
||||
},
|
||||
{
|
||||
"name": "Travia",
|
||||
"grad": 2
|
||||
},
|
||||
{
|
||||
"name": "Boron",
|
||||
"grad": 2
|
||||
},
|
||||
{
|
||||
"name": "Hesinde",
|
||||
"grad": 2
|
||||
},
|
||||
{
|
||||
"name": "Firun",
|
||||
"grad": 2
|
||||
},
|
||||
{
|
||||
"name": "Tsa",
|
||||
"grad": 2
|
||||
},
|
||||
{
|
||||
"name": "Phex",
|
||||
"grad": 2
|
||||
},
|
||||
{
|
||||
"name": "Peraine",
|
||||
"grad": 2
|
||||
},
|
||||
{
|
||||
"name": "Ingrerimm",
|
||||
"grad": 2
|
||||
},
|
||||
{
|
||||
"name": "Rahja",
|
||||
"grad": 2
|
||||
}
|
||||
],
|
||||
"reichweite": "Berührung",
|
||||
"ziel": "1 Person",
|
||||
"zauberdauer": "1/2 Stund (Andacht)",
|
||||
"wirkungsdauer": "permanent; kann nur durch eine Exkommunikation aufgehoben werden",
|
||||
"auswirkung": {
|
||||
"II": "Zwölfjährige oder Bekehrte werden mittels dieser Liturgie in den Zwölfgötterkult eingeführt, ihren Seelen steht prinzipiell eines der zwölfgöttlichen Paradiese offen. Im Zuge der Initiation erkennen Geweihte auch, ob Kinder potenzielle Novizen darstellen."
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
{
|
||||
"name": "Objektweihe",
|
||||
"alias": [],
|
||||
"grad": 1,
|
||||
"herkunft": [
|
||||
{
|
||||
"name": "Praios",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rondra",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Efferd",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Travia",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Boron",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Hesinde",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Firun",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Tsa",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Phex",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Peraine",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Ingrerimm",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rahja",
|
||||
"grad": 1
|
||||
}
|
||||
],
|
||||
"reichweite": "Berührung",
|
||||
"ziel": "1 Objekt",
|
||||
"zauberdauer": "mehrere Stunden (Zeremonie)",
|
||||
"wirkungsdauer": "solang sich der Träger des Objekts der jeweiligen Gottheit gefällig verhält oder bis die gespeicherte Segnung ausgelöst wurde, maximal LkP* Wochen",
|
||||
"auswirkung": {
|
||||
"I": "Diese Liturgie bindet neine der Zwölf Segnungen in einen Gegenstand. Die Wirkung dieser Segnung kann dann mit einer Anrufung der Gottheit (1 Aktion) jederzeit hervorgeholt werden. Der Gegenstand verliert seine Weihe damit jedoch. Solange der Gegenstand geweiht ist, ist er durch profane Gewalteinwirkung unzerstörbar. Handelt es sich um eine Rüstung, steigt der RS um LkP*/4 Punkte, jedoch nur im Kampf gegen unheilige Wesenheiten."
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
"name": "Eidsegen",
|
||||
"alias": [],
|
||||
"grad": 1,
|
||||
"primärHerkunft": "",
|
||||
"herkunft": [
|
||||
{
|
||||
"name": "Praios",
|
||||
"grad": 0
|
||||
},
|
||||
{
|
||||
"name": "Rondra",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Efferd",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Travia",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Boron",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Hesinde",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Firun",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Tsa",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Phex",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Peraine",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Ingrerimm",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rahja",
|
||||
"grad": 1
|
||||
}
|
||||
],
|
||||
"reichweite": "Berührung",
|
||||
"ziel": "1 Person",
|
||||
"zauberdauer": "1 Spielrunde (Gebet)",
|
||||
"wirkungsdauer": "frei festzulegen, lägstens aber LkP* Monate",
|
||||
"auswirkung": {
|
||||
"I": "Der Schwur einer Person wird mit dieser Liturgie bekräftigt. Wer den Eid ablegt, nennt dabei eine Strafe, die ihn bei Eidbruch ereilen soll. Diese Strafe sollte einem regeltechnischen Nachteil entsprechen. Wird der Eid gebrochen, trifft ihn dieser Nachteil. Zusätzlich wirken Liturgien, von denen der Eidbrüchige profitieren würde, auf ihn nur mit halber Stärke."
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
"name": "Feuersegen",
|
||||
"alias": [],
|
||||
"grad": 1,
|
||||
"primärHerkunft": "Ingerimm",
|
||||
"herkunft": [
|
||||
{
|
||||
"name": "Praios",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rondra",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Efferd",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Travia",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Boron",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Hesinde",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Firun",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Tsa",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Phex",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Peraine",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Ingrerimm",
|
||||
"grad": 0
|
||||
},
|
||||
{
|
||||
"name": "Rahja",
|
||||
"grad": 1
|
||||
}
|
||||
],
|
||||
"reichweite": "selbst / Sicht (Variante des Feuerschutzes)",
|
||||
"ziel": "Gewewihter / 1 Gegenstand (Variante des Feuerschutzes)",
|
||||
"zauberdauer": "1 Spielrunde (Gebet)",
|
||||
"wirkungsdauer": "bis zum Ende der Probe, maximal LkP* Tage",
|
||||
"auswirkung": {
|
||||
"I": "Aus der Fingerspitze des Geweihten schlägt ein Flämmchen, das gegen Wind und Wetter geschützt ist; es verlischt nur, wenn es in Wasser getaucht wird / In dieser Variante schützt der Geweihte ein Feuer mit einer Brennfläche von maximal einem Rechtschritt, das so nicht verlöschen kann, solange genug Brennmaterial nachgelegt wird."
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
"name": "Geburtssegen",
|
||||
"alias": [],
|
||||
"grad": 1,
|
||||
"primärHerkunft": "Tsa",
|
||||
"herkunft": [
|
||||
{
|
||||
"name": "Praios",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rondra",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Efferd",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Travia",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Boron",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Hesinde",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Firun",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Tsa",
|
||||
"grad": 0
|
||||
},
|
||||
{
|
||||
"name": "Phex",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Peraine",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Ingrerimm",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rahja",
|
||||
"grad": 1
|
||||
}
|
||||
],
|
||||
"reichweite": "Berührung",
|
||||
"ziel": "1 Person",
|
||||
"zauberdauer": "1 Spielrunde (Gebet)",
|
||||
"wirkungsdauer": "bis zum 12. Geburtstag des Kindes",
|
||||
"auswirkung": {
|
||||
"I": "Die Liturgie schützt ein Kind vor dämonischen Einflüsterungen und Entführung durch Kobolde. Entsprechende Proben sind um 12 Punkte erschwert."
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
"name": "Geburtssegen",
|
||||
"alias": [],
|
||||
"grad": 1,
|
||||
"primärHerkunft": "Phex",
|
||||
"herkunft": [
|
||||
{
|
||||
"name": "Praios",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rondra",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Efferd",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Travia",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Boron",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Hesinde",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Firun",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Tsa",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Phex",
|
||||
"grad": 0
|
||||
},
|
||||
{
|
||||
"name": "Peraine",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Ingrerimm",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rahja",
|
||||
"grad": 1
|
||||
}
|
||||
],
|
||||
"reichweite": "Berührung",
|
||||
"ziel": "1 Person",
|
||||
"zauberdauer": "6 Aktionen (Stoßgebet)",
|
||||
"wirkungsdauer": "LkP* Spielrunden, maximal bis zur nächsten Talentprobe",
|
||||
"auswirkung": {
|
||||
"I": "Wer diesen Segen empfängt, darf einmal eine Probe wiederholen und das für ihn günstigere Ergebnis wählen. Dies funktioniert jedoch nicht mit Fertigkeiten, die beim segnenden Geweihten unter Mirakel- gelistet sind."
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
"name": "Grabsegen",
|
||||
"alias": [],
|
||||
"grad": 1,
|
||||
"primärHerkunft": "Boron",
|
||||
"herkunft": [
|
||||
{
|
||||
"name": "Praios",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rondra",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Efferd",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Travia",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Boron",
|
||||
"grad": 0
|
||||
},
|
||||
{
|
||||
"name": "Hesinde",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Firun",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Tsa",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Phex",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Peraine",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Ingrerimm",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rahja",
|
||||
"grad": 1
|
||||
}
|
||||
],
|
||||
"reichweite": "Berührung",
|
||||
"ziel": "1 Person",
|
||||
"zauberdauer": "1 Spielrunde (Gebet)",
|
||||
"wirkungsdauer": "permanent; es sei denn, das Grab wird entweiht.",
|
||||
"auswirkung": {
|
||||
"I": "Das Grab eines solcherart Gesegneten wirkt abschreckend auf Grabräuber und verhindert nekromantische Rituale, sodass der Leichnam schwerer zu einem Untoten erhoben werden kann. Sterblichen, die sich am Grab vergehenwollen, muss eine MU-Probe erschwert um eventuell vorhandene Totenangst gelingen. Zauber, die den Geist oder den Leichnam des Toten betreffen, sind um LkP*/2 Punkte erschwert."
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
"name": "Harmoniesegen",
|
||||
"alias": [],
|
||||
"grad": 1,
|
||||
"primärHerkunft": "Rahja",
|
||||
"herkunft": [
|
||||
{
|
||||
"name": "Praios",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rondra",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Efferd",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Travia",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Boron",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Hesinde",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Firun",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Tsa",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Phex",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Peraine",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Ingrerimm",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rahja",
|
||||
"grad": 0
|
||||
}
|
||||
],
|
||||
"reichweite": "Berührung",
|
||||
"ziel": "1 Person",
|
||||
"zauberdauer": "12 Aktionen (Stoßgebet)",
|
||||
"wirkungsdauer": "permanent; es sei denn, das Grab wird entweiht.",
|
||||
"auswirkung": {
|
||||
"I": "Die gesegnete Person wird innerlich ausgeglichen und zuversichtlich. Proben auf MU, IN und CH sind um LkP*/2 Punkte erleichtert, Proben auf Schlechte Eigenschaften ebenso erschwert. Zauber, die den so Gesegneten geistig verwirren oder aufregen sollen (wie etwa der HORRIPHOBUS), werden in ihrer von den ZfP* abhängigen Wirkungsstärke um LkP*/2 Punkte vermindert. Fallen die ZfP* dabei unter 0, endet der Zauber."
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
"name": "Heilungssegen",
|
||||
"alias": [],
|
||||
"grad": 1,
|
||||
"primärHerkunft": "Peraine",
|
||||
"herkunft": [
|
||||
{
|
||||
"name": "Praios",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rondra",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Efferd",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Travia",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Boron",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Hesinde",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Firun",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Tsa",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Phex",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Peraine",
|
||||
"grad": 0
|
||||
},
|
||||
{
|
||||
"name": "Ingrerimm",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rahja",
|
||||
"grad": 1
|
||||
}
|
||||
],
|
||||
"reichweite": "selbst/ Berührung",
|
||||
"ziel": "Geweihte / 1 Person",
|
||||
"zauberdauer": "1 Spielrunde (Gebet)",
|
||||
"wirkungsdauer": "augenblicklich",
|
||||
"auswirkung": {
|
||||
"I": "Der Nutznießer dieser Liturgie (dies kann sowohl der Geweihte selbst als auch eine weitere Person sein) erhält LkP*/2+3 Lebenspunkte zurück. Hierdurch schließen sich jedoch keine regeltechnischen Wunden."
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
"name": "Märtyrersegen",
|
||||
"alias": [],
|
||||
"grad": 1,
|
||||
"primärHerkunft": "Firun",
|
||||
"herkunft": [
|
||||
{
|
||||
"name": "Praios",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rondra",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Efferd",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Travia",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Boron",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Hesinde",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Firun",
|
||||
"grad": 0
|
||||
},
|
||||
{
|
||||
"name": "Tsa",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Phex",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Peraine",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Ingrerimm",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rahja",
|
||||
"grad": 1
|
||||
}
|
||||
],
|
||||
"reichweite": "selbst",
|
||||
"ziel": "Geweihter",
|
||||
"zauberdauer": "4 Aktionen",
|
||||
"wirkungsdauer": "permanent; es sei denn, das Grab wird entweiht.",
|
||||
"auswirkung": {
|
||||
"I": "Der Geweihte spürt keinen Schmerz: Er erleidet keine Abzüge durch niedrige LeP oder Wunden, auch stirbt er nicht. Erst mit Ende der Wirkungsdauer offenbaren sich dem Geweihten die Folgen des Kampfes. Der Meister sollte darum währenddessen den erlittenen Schaden verdeckt notieren. Der Selbstbeherrschungs-Wert des Gesegneten steigt darüber hinaus um LkP*/2 Punkte."
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
"name": "Schutzsegen",
|
||||
"alias": [],
|
||||
"grad": 1,
|
||||
"primärHerkunft": "Rondra",
|
||||
"herkunft": [
|
||||
{
|
||||
"name": "Praios",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rondra",
|
||||
"grad": 0
|
||||
},
|
||||
{
|
||||
"name": "Efferd",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Travia",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Boron",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Hesinde",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Firun",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Tsa",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Phex",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Peraine",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Ingrerimm",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rahja",
|
||||
"grad": 1
|
||||
}
|
||||
],
|
||||
"reichweite": "Berührung",
|
||||
"ziel": "Zone von 10 Schritt Radius",
|
||||
"zauberdauer": "10 Aktionen (Stoßgebet)",
|
||||
"wirkungsdauer": "LkP* Spielrunden",
|
||||
"auswirkung": {
|
||||
"I": "eine bestimmte Art von unheiligen Kreaturen kann den so geschützten Boden nur dann betreten, wenn ihre Magieresistenz höher ist als LkP*/2. Sie erleiden dort außerdem Schaden in Höhe von 1W6 SP pro Spielrunde bzw. sogar 1W6 SP pro Kampfrunde, falls es sich bei der gebannten Art um einen der Gottheit des Geweihten entgegengesetzten Dämon handelt (oder um eine Untotenart bei einem Borongeweihten). Der Geweihte muss nicht unbedingt wissen, worum es sich bei einem Wesen, das er abhalten möchte, genau handelt; es muss nur klarsein, welches Wesen er meint, und alle gleichartigen Kreaturen werden ebenfalls ferngehalten."
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
"name": "Speisesegen",
|
||||
"alias": [],
|
||||
"grad": 1,
|
||||
"primärHerkunft": "Travia",
|
||||
"herkunft": [
|
||||
{
|
||||
"name": "Praios",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rondra",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Efferd",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Travia",
|
||||
"grad": 0
|
||||
},
|
||||
{
|
||||
"name": "Boron",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Hesinde",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Firun",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Tsa",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Phex",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Peraine",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Ingrerimm",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rahja",
|
||||
"grad": 1
|
||||
}
|
||||
],
|
||||
"reichweite": "Berührung",
|
||||
"ziel": "mehrere Gegenstände",
|
||||
"zauberdauer": "8 Aktionen (Stoßgebet)",
|
||||
"wirkungsdauer": "augenblicklich",
|
||||
"auswirkung": {
|
||||
"I": "Der Segen macht eine Mahlzeit von zweifelhafter Qualität für bis zu LkW Personen genießbar und durchschnittlich schmackhaft. Krankheiten bis zu einer Stufe von LkP*/2 die durch diese Mahlzeit aufgetreten wären, werden verhindert, hinzugefügtes Gift wird jedoch nicht neutralisiert."
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
"name": "Tranksegen",
|
||||
"alias": [],
|
||||
"grad": 1,
|
||||
"primärHerkunft": "Efferd",
|
||||
"herkunft": [
|
||||
{
|
||||
"name": "Praios",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rondra",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Efferd",
|
||||
"grad": 0
|
||||
},
|
||||
{
|
||||
"name": "Travia",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Boron",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Hesinde",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Firun",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Tsa",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Phex",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Peraine",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Ingrerimm",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rahja",
|
||||
"grad": 1
|
||||
}
|
||||
],
|
||||
"reichweite": "Berührung",
|
||||
"ziel": "mehrere Gegenstände",
|
||||
"zauberdauer": "8 Aktionen (Stoßgebet)",
|
||||
"wirkungsdauer": "augenblicklich",
|
||||
"auswirkung": {
|
||||
"I": "Der Segen macht Getränke (hauptsächlich Wasser), die für bis zu LkW Personen einen Tag lang ausreichen, genießbar. Krankheiten bis zu einer Stufe von LkP*/2, die durch diese Getränke aufgetreten wären, werden verhindert, hinzugefügtes Gift wird jedoch nicht neutralisiert. Meerwasser kann hiermit in Trinkwasser gewandelt werden."
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
"name": "Weisheitssegen",
|
||||
"alias": [],
|
||||
"grad": 1,
|
||||
"primärHerkunft": "Hesinde",
|
||||
"herkunft": [
|
||||
{
|
||||
"name": "Praios",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rondra",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Efferd",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Travia",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Boron",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Hesinde",
|
||||
"grad": 0
|
||||
},
|
||||
{
|
||||
"name": "Firun",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Tsa",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Phex",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Peraine",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Ingrerimm",
|
||||
"grad": 1
|
||||
},
|
||||
{
|
||||
"name": "Rahja",
|
||||
"grad": 1
|
||||
}
|
||||
],
|
||||
"reichweite": "selbst/ Berührung",
|
||||
"ziel": "Geweihter / 1 Person",
|
||||
"zauberdauer": "15 Aktionen (Stoßgebet)",
|
||||
"wirkungsdauer": "LkP* Stunden",
|
||||
"auswirkung": {
|
||||
"I": "Der so Gesegnete (der Geweihte oder eine andere Person) gewinnt göttliche Einsichten und ist gefeit gegen Torheit. Er verteilt möglichst gleichwertig LkP*/2 Punkte auf KL und IN, außerdem steigt seine MR um LkP*/4 Punkte."
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,5 @@
|
|||
{
|
||||
"_id": "XxPXNovZd9AX2sHM",
|
||||
"_key": "!items!XxPXNovZd9AX2sHM",
|
||||
"type": "Skill",
|
||||
"name": "Abrichten",
|
||||
"system": {
|
||||
"gruppe": "Handwerk",
|
||||
"probe": [
|
||||
"MU",
|
||||
|
|
@ -14,5 +10,4 @@
|
|||
],
|
||||
"behinderung": "situationsbedingt",
|
||||
"talent": "Wann immer ein Held seinem Tier ein Kunststück (einem Pferd den ‘stummen Alarm’, einem Hund das Apportieren oder Männchen machen) beibringen will, ist eine Probe auf Abrichten fällig. Zuschläge auf die Probe entstehen durch Fehlversuche (+2 für jede gescheiterte Probe), durch die Schwierigkeit des Kunststücks und die grundsätzliche Lernfähigkeit und potentielle Loyalität des Tieres. Übungen, die einem Tier wegen körperlicher oder geistiger Beschränkungen nicht möglich sind, kann ihm auch ein meisterlicher Abrichter nicht beibringen."
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,5 @@
|
|||
{
|
||||
"_id": "w3wHyimJXv6EjnMw",
|
||||
"_key": "!items!w3wHyimJXv6EjnMw",
|
||||
"type": "Skill",
|
||||
"name": "Ackerbau",
|
||||
"system": {
|
||||
"gruppe": "Handwerk",
|
||||
"probe": [
|
||||
"IN",
|
||||
|
|
@ -14,5 +10,4 @@
|
|||
],
|
||||
"behinderung": "situationsbedingt",
|
||||
"talent": "Dies ist die grundlegende Kenntnis von Bodenverhältnissen, Aussaat und Ernte, Feldbestellungs- und Lagerungsmethoden. Mit dem Talent kann man Nutzpflanzen erkennen und unterscheiden und auf diese Art und Weise z.B. eine auf einer einsamen Insel gestrandete Heldengruppe vor dem Verhungern bewahren. Zudem erkennt ein Ackerbau-Kundiger leicht Wert und Haltbarkeit von Nahrungsmitteln. Auf der aktiven Seite heißt dies auch, dass ein entsprechend ausgebildeter Held mit Pflug, Hacke und Dreschflegel umzugehen weiß."
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,5 @@
|
|||
{
|
||||
"_id": "peize2dihvjf2N7p",
|
||||
"_key": "!items!peize2dihvjf2N7p",
|
||||
"type": "Skill",
|
||||
"name": "Akrobatik",
|
||||
"system": {
|
||||
"gruppe": "Körperlich",
|
||||
"probe": [
|
||||
"MU",
|
||||
|
|
@ -18,5 +14,4 @@
|
|||
],
|
||||
"behinderung": "*2",
|
||||
"talent": "In diesem Talent sind die Dinge zusammengefasst, in denen sich Gaukler seit ihrer Kindheit üben: Balancieren, Schwingen an Seilen und Trapezen, Radschlagen und halsbrecherische Salti. Wann immer ein Held eine Aktion unternimmt, die eines Zirkusartisten würdig wäre – also bei allen willentlich ausgeführten akrobatischen Aktionen –, können Sie als Meister eine Akrobatik-Probe verlangen. Eher ‘gewöhnliche’ Aktionen der Körperbeherrschung, wie speziell das Abrollen nach Stürzen, fallen unter das Talent Körperbeherrschung."
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,5 @@
|
|||
{
|
||||
"_id": "EHrjrxETwhx1mB63",
|
||||
"_key": "!items!EHrjrxETwhx1mB63",
|
||||
"type": "Skill",
|
||||
"name": "Sprachen kennen: Alaani",
|
||||
"system": {
|
||||
"name": "Sprachen kennen Alaani",
|
||||
"gruppe": "Sprachen",
|
||||
"probe": [
|
||||
"KL",
|
||||
|
|
@ -14,5 +10,4 @@
|
|||
],
|
||||
"komplexität": "21",
|
||||
"talent": "Ähnlich wie bei den Schriften wird jede aventurische Sprache als eigenes Talent gewertet. Je der Aventurier beherrscht seine Muttersprache auf einem Startwert in Höhe seiner Klugheit–2, manche darüber hinaus noch eine Zweitsprache in Höhe von KL –4. Weitere Sprachen müssen dann explizit erlernt werden.<br/>Um die Sprache identifizieren zu können, ist ein TaW von 1 nötig, um grundlegende Konzepte (“Ich Hunger”) verstehen und vermitteln zu können, ist ein TaW von 2 nötig; um einfache Sätze bilden und verstehen zu können, benötigt man einen TaW von 4. Ein TaW von 1/3 der Komplexität bedeutet recht fließenden Umgang mit allen üblichen grammatischen Konstruktionen und die Kenntnis auch seltener Wörter, während ein TaW in Höhe der halben Komplexität heißt, dass man die Sprache so gut wie ein durchschnittlicher Einheimischer beherrscht (wenn man auch immer noch einen leichten Akzent aufweist). Selbst philosophische oder magietheoretische Schriften gehen selten über eine Komplexität von 15 hinaus."
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,5 @@
|
|||
{
|
||||
"_id": "oHnVR4rpCZes1MBk",
|
||||
"_key": "!items!oHnVR4rpCZes1MBk",
|
||||
"type": "Skill",
|
||||
"name": "Alchimie",
|
||||
"system": {
|
||||
"gruppe": "Handwerk",
|
||||
"probe": [
|
||||
"MU",
|
||||
|
|
@ -22,5 +18,4 @@
|
|||
],
|
||||
"behinderung": "situationsbedingt",
|
||||
"talent": "Dieses Talent regelt die Herstellung ‘normaler’ Chemikalien und wundertätiger Mittel. Der Spieler teilt dem Meister mit, welches alchimistische Gemisch sein Held herstellen will, und der Spielleiter legt den Zuschlag (oder Abzug) auf die erforderliche Probe fest. Bevor es zur Probe kommt, muss der Held natürlich erst einmal in den Besitz der benötigten Zutaten und auch der Rezeptur kommen. Eine gescheiterte Probe auf diesem gefährlichen Gebiet kann mancherlei bewirken: ein harmloses, aber bestialisch stinkendes, grünes Wölkchen zum Beispiel, oder aber einen Urknall, der ein halbes Stadtviertel in Schutt und Asche legt. Der Meister sollte so fair sein, seinen Helden in etwa anzudeuten, was eine gescheiterte Probe für sie bedeuten könnte. Talentproben in Alchimie können auch zur Analyse unbekannter Mixturen dienen – aber auch auf diesem Gebiet kann ein Irrtum verhängnisvolle Folgen haben (und hier sollte der Meister auch ruhig verdeckt würfeln)."
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,5 @@
|
|||
{
|
||||
"_id": "WPbhXQhGbNMxEyO1",
|
||||
"_key": "!items!WPbhXQhGbNMxEyO1",
|
||||
"type": "Skill",
|
||||
"name": "Anatomie",
|
||||
"system": {
|
||||
"gruppe": "Wissen",
|
||||
"probe": [
|
||||
"MU",
|
||||
|
|
@ -17,5 +13,4 @@
|
|||
}
|
||||
],
|
||||
"talent": "Die Kunde von den Körpern, ihren inneren Zusammenhängen und ihrem Aufbau ist eine der grundlegenden Wissenschaften für die Heilkunst. Da diese Kunst nur an Leichen oder Verurteilten gewonnen werden kann, ist der Beruf des Anatomen nicht sonderlich angesehen, ja, vielerorts sogar verboten. Dafür ist ein gebildeter Anatom aber auch in der Lage, schwere Wunden und bestimmte Arten von Organkrankheiten sofort als solche zu erkennen und zu behandeln (Erleichterung entsprechender Heilkunde-Proben um den halben TaW Anatomie). Zudem kennt er die verwundbarsten Punkte des menschlichen Körpers und richtet daher im waffenlosen Kampf stets 1 TP mehr an als ein unkundiger Kämpfer, wenn er über einen Anatomie-TaW von 10 oder mehr verfügt."
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,5 @@
|
|||
{
|
||||
"_id": "1rZ9ZOobBzOWfqVT",
|
||||
"_key": "!items!1rZ9ZOobBzOWfqVT",
|
||||
"type": "Skill",
|
||||
"name": "Anderthalbhänder",
|
||||
"system": {
|
||||
"gruppe": "Kampf",
|
||||
"talent": "Die meisten ‘anderthalbhändig’ geführten Schwerter und Säbel können zwar – je nach Körperkraft des Helden – auch mit den Talenten Schwerter, Säbel oder Zweihandschwerter/-säbel geführt werden, ihre wahren Fähigkeiten erkennt man jedoch nur, wenn man die für sie typischen Manöver in einer Kampftechnik erlernt hat: der schnelle Wechsel von einhän-diger zu zweihändiger Führung und zurück, daher auch der Name ‘anderthalbhändig’. Trotz ihres nicht unbeträchtlichen Gewichts können gut geführte Anderthalbhänder ein fast so variantenreiches Klingenspiel ermöglichen wie Fechtwaffen, weswegen dieses Talent auch gerne als die ‘Königsdisziplin’ unter den Klingenwaffen angesehen wird."
|
||||
}
|
||||
}
|
||||