feature/spells (#53)

implements spells and liturgies
feature/spells^2
macniel 2025-10-09 21:09:31 +02:00
parent b08884426d
commit 5b76df3653
218 changed files with 2686 additions and 842 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
dist
node_modules
src/packs/__source

View File

@ -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>

View File

@ -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
)

BIN
src/assets/Aves.png 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
src/assets/Kor.png 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
src/assets/Phex.png 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
src/assets/Tsa.png 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

View File

@ -13,6 +13,9 @@ 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";
async function preloadHandlebarsTemplates() {
return loadTemplates([
@ -26,7 +29,8 @@ async function preloadHandlebarsTemplates() {
'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 +55,8 @@ Hooks.once("init", () => {
Spell: SpellDataModel,
Advantage: VornachteileDataModel,
Equipment: EquipmentDataModel,
Liturgy: LiturgyDataModel,
Blessing: BlessingDataModel
}
CONFIG.Combat.initiative = {
@ -97,6 +103,11 @@ Hooks.once("init", () => {
makeDefault: true,
label: 'DSA41.AusruestungLabels.Item'
})
Items.registerSheet('dsa41.liturgy', LiturgySheet, {
types: ["Liturgy"],
makeDefault: true,
label: 'DSA41.LiturgyLabels.Item'
})
return preloadHandlebarsTemplates();
})

View File

@ -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}),
}
}
}

View File

@ -107,23 +107,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}),

View File

@ -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() {
}
}

View File

@ -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
}
}

View File

@ -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(),

View File

@ -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('');
}
}
}

View File

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

View File

@ -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,44 @@ 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;
// evaluate deities for KaP
systemData.rs = 0;
systemData.kap.max = 0;
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)
}

View File

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

View File

@ -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() {

View File

@ -1,5 +1,7 @@
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 */
@ -23,25 +25,28 @@ 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 "Equipment":
return characterSheet.#handleDroppedEquipment(actor, document);
case "Liturgy":
return characterSheet.#handleDroppedLiturgy(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) {
@ -96,6 +101,63 @@ export class CharacterSheet extends ActorSheet {
);
}
#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;
this.#addSkillsToContext(context)
this.#addAdvantagesToContext(context)
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;
}
#addAttributesToContext(context) {
const actorData = context.data;
context.attributes = [
@ -267,7 +329,7 @@ export class CharacterSheet extends ActorSheet {
}
prepareEigenschaftRoll(actorData, name) {
if (name) {
if (name && name !== "*") {
return actorData.system.attribute[name.toLowerCase()].aktuell
} else {
return 0
@ -533,6 +595,116 @@ 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;
}
}
}
#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);
@ -555,21 +727,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
@ -654,57 +837,77 @@ 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;
}
}
}
}

View File

@ -0,0 +1,48 @@
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)
}
}

View File

@ -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
@ -266,19 +336,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]

View File

@ -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*."
}
}

View File

@ -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."
}
}

View File

@ -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."
}
}

View File

@ -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."
}
}

View File

@ -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."
}
}

View File

@ -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."
}
}

View File

@ -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."
}
}

View File

@ -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."
}
}

View File

@ -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."
}
}

View File

@ -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."
}
}

View File

@ -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."
}
}

View File

@ -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."
}
}

View File

@ -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."
}
}

View File

@ -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."
}
}

View File

@ -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."
}
}

View File

@ -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."
}
}

View File

@ -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."
}
}

View File

@ -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."
}
}

View File

@ -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."
}
}

View File

@ -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."
}
}

View File

@ -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ß."
}
}

View File

@ -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."
}
}

View File

@ -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 Klugheit2, 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."
}
}

View File

@ -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)."
}
}

View File

@ -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."
}
}

View File

@ -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."
}
}

View File

@ -1,10 +1,5 @@
{
"_id": "Gaz7algdJ98nYFdW",
"_key": "!items!Gaz7algdJ98nYFdW",
"type": "Skill",
"name": "Armbrust",
"system": {
"gruppe": "Kampf",
"talent": "Zwar beziehen auch diese Waffen ihre Energie aus gespannten Bögen, verdrillten Sehnen oder mechanischen Federn, aber damit enden die Ähnlichkeiten mit Bögen auch schon. Alle armbrustähnlichen Waffen besitzen einen Schaft, einen Abzug und einen Spannmechanismus und sind prinzipiell durch Ausrichten aufs Ziel nund Auslösen des Abzugs abzuschießen."
}
}

View File

@ -1,9 +1,5 @@
{
"_id": "1irLbG8YJ8Q70nnK",
"_key": "!items!1irLbG8YJ8Q70nnK",
"type": "Skill",
"name": "Sprachen kennen: Atak",
"system": {
"name": "Sprachen kennen Atak",
"gruppe": "Sprachen",
"probe": [
"KL",
@ -14,5 +10,4 @@
],
"komplexität": "12",
"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 Klugheit2, 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."
}
}

View File

@ -1,9 +1,5 @@
{
"_id": "c7TF5srKLVX2LY4e",
"_key": "!items!c7TF5srKLVX2LY4e",
"type": "Skill",
"name": "Athletik",
"system": {
"gruppe": "Körperlich",
"probe": [
"GE",
@ -14,5 +10,4 @@
],
"behinderung": "*2",
"talent": "Dies ist die Fähigkeit, Kraft, Gewandtheit und Konstitution auf einen Punkt zu konzentrieren und in den klassischen athletischen Disziplinen zu brillieren, nur selten, um damit den Lorbeerkranz in einer entsprechenden Veranstaltung zu erringen, sondern meist, weil es zum Berufsbild gehört, lange Strecken zu laufen oder schwere Lasten zu stemmen. Athletik ist der aktive Einsatz der körperlichen Fähigkeiten (im Gegensatz zum Talent Körperbeherrschung, das bei Reaktionen auf äußere Ereignisse zum Einsatz kommt). Athletik-Proben können abgelegt werden, um die Sprintgeschwindigkeit zu erhöhen, den Ausdauerverlust bei Langstreckenläufen zu vermindern, eine KK-Probe beim Gewichtheben zu unterstützen oder die übliche Sprungreichweite und -höhe zu vergrößern."
}
}

View File

@ -1,9 +1,5 @@
{
"_id": "LIxUN4SY7uqj716y",
"_key": "!items!LIxUN4SY7uqj716y",
"type": "Skill",
"name": "Bergbau",
"system": {
"gruppe": "Handwerk",
"probe": [
"IN",
@ -14,5 +10,4 @@
],
"behinderung": "situationsbedingt",
"talent": "Diese Talent umfasst das sachgerechte Anlegen von Tunneln und Schächten und deren Luftversorgung und Wasserentsorgung. Außerdem ermöglichen Kenntnisse im Bergbau die Beurteilung von unterirdischen Anlagen: Welche Wesen haben sie geschaffen? Wo wurden bauliche Veränderungen vorgenommen? Solche und ähnliche Fragen müssen vom Meister nach einer gelungener Bergbau-Probe des Helden beantwortet werden. Dass sich die meisten aventurischen Zwerge fast von Natur aus auf solche Kenntnisse verstehen, verwundert nicht."
}
}

View File

@ -1,9 +1,5 @@
{
"_id": "oMOnOMtQmZJBRney",
"_key": "!items!oMOnOMtQmZJBRney",
"type": "Skill",
"name": "Betören",
"system": {
"gruppe": "Gesellschaft",
"probe": [
"IN",
@ -18,5 +14,4 @@
],
"behinderung": "-2",
"talent": "Die Ausstrahlung auf das andere Geschlecht der eigenen Spezies wird durch dieses Talent bewertet. Eine gelungene Talentprobe besagt, dass das Opfer der Annäherungsversuche dem Helden gewogen ist. Was die betörte Persen harten Nüssen beiderlei Geschlechts kann der Meister die Betören-Probe mit Zuschlägen versehen. Will ein Held versuchen, ein Mitglied einer anderen Art (speziell zwischen Elfen und Zwergen) zu betören, dann sollte der Meister deutliche Probenzuschläge verlangen; weniger heftige Zuschläge sind für Betörungsversuche gegenüber dem eigenen Geschlecht erforderlich."
}
}

View File

@ -1,10 +1,5 @@
{
"_id": "Msv0BWdwlNlF2ETU",
"_key": "!items!Msv0BWdwlNlF2ETU",
"type": "Skill",
"name": "Bogen",
"system": {
"gruppe": "Kampf",
"talent": "Bögen sind die Waffe der Wahl für die Bewohner von Steppen, Wüsten und Auen, weswegen sowohl die Elfen wie auch die Orks, die Weidener wie auch die Novadis für ihre Künste mit dem Bogen bekannt sind. Die Größe dieser Schusswaffen reicht vom kompakten Kurzbogen der Novadis bis zum Weidener Langbogen. Der korrekte Umgang mit Pfeil und Bogen erfordert einiges an Übung."
}
}

View File

@ -1,9 +1,5 @@
{
"_id": "FfCHnaMJj7yVr04i",
"_key": "!items!FfCHnaMJj7yVr04i",
"type": "Skill",
"name": "Bogenbau",
"system": {
"gruppe": "Handwerk",
"probe": [
"KL",
@ -18,5 +14,4 @@
],
"behinderung": "situationsbedingt",
"talent": "Bogenbauer und Armbruster beschäftigen sich mit der Herstellung von Schusswaffen und sind die einzigen, die auf Spannung basierende, Projektile verschießende Fernwaffen (und die dazugehörigen Projektile) bauen können. Natürlich können sie auch die Qualität solcher Waffen einschätzen. Im Band Wege des Schwerts stellen wir Ihnen ein detailliertes System zum Bau von Schusswaffen vor; im Rahmen dieser Basisregeln gilt folgende Vorgehensweise: Um einen Bogen oder eine Armbrust herzustellen, benötigt man die richtigen Materialien für Bogen und Sehne (zusätzlich bei der Armbrust für Schaft und Abzug) und muss eine bestimmte Anzahl von Talentproben ablegen. Jede Probe dauert einen halben Tag; bei Misslingen einer Probe kann man versuchen zu retten, was noch zu retten ist, und eine Probe ablegen, die um den doppelten Betrag erschwert ist. Misslingt auch diese, ist die gesamte Waffe missraten und das Material verdorben.<br/>Um Pfeile oder Bolzen herzustellen, ist neben geeignetem Holz und vorhandenen Spitzen noch eine Bogenbau-Probe nötig, um die Spitze und vorallem die Befiederung korrekt anzubringen. Der Zuschlag auf der Probe ist der Tabelle zu entnehmen. Jede Probe zum Herstellen eines Geschosses dauert eine halbe Stunde.<table><tr><th>Typ</th><th>Herstellen</th><th>Geschoss</th></tr><tr><td>Kurzbogen</td><td>4 Proben</td><td>Probe</td></tr><tr><td>Langbogen</td><td>6 Proben</td><td>Probe +1</td></tr><tr><td>Kriegsbogen</td><td>7 Proben</td><td>2 Proben + 3</td></tr><tr><td>Leichte Armbrust</td><td>4 Proben</td><td>2 Proben -1</td></tr><tr><td>Schwere Armbrust</td><td>12 Proben</td><td>2 Proben +1</td></tr><table>"
}
}

View File

@ -1,9 +1,5 @@
{
"_id": "usmU8Ig2qragLaNd",
"_key": "!items!usmU8Ig2qragLaNd",
"type": "Skill",
"name": "Boote Fahren",
"system": {
"gruppe": "Handwerk",
"probe": [
"GE",
@ -14,5 +10,4 @@
],
"behinderung": "situationsbedingt",
"talent": "Alle Talente, die zur Fortbewegung eines kleinen Wasserfahrzeuges dienen - Rudern, Segeln, Paddeln, Staken - sind hier zusammengefasst. Der Meister sollte es den Helden gestatten, ohne Probe gemächlich über einen stillen Teich zu rudern - irgendwie wird der Held schon ans andere Ufer gelangen. Segeln, Wildwasserfahrten und ähnliche Aktionen sind nur mit gelungener Probe möglich. Für die Handhabung größerer Segel- oder Ruderschiffe sind das Talent SEEFAHRT und eine gröere Anzahl von Matrosen nötig."
}
}

View File

@ -1,9 +1,5 @@
{
"_id": "wblRtqxrcKlv1spJ",
"_key": "!items!wblRtqxrcKlv1spJ",
"type": "Skill",
"name": "Sprachen kennen: Bosparano",
"system": {
"name": "Sprachen kennen Bosparano",
"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 Klugheit2, 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."
}
}

View File

@ -1,9 +1,5 @@
{
"_id": "ydmXvfh98fVJ0T7R",
"_key": "!items!ydmXvfh98fVJ0T7R",
"type": "Skill",
"name": "Brett-/Kartenspiel",
"system": {
"gruppe": "Wissen",
"probe": [
"KL",
@ -13,5 +9,4 @@
"voraussetzung": [
],
"talent": "Die Kenntnis der verschiedensten Brettspiele (wie z.B. Urdas, Garadan, das thorwalsche Hneftafl oder das weit verbreitete und vielfach variierte tulamidische Kamelspiel) sowie Kartenspiele (hier namentlich das verbreitete Boltan- oder Fünfas-Spiel) gehören zu dieser Fertigkeit, die nicht nur Regelkunde, sondern auch Spieltechnik, Gewinnkombinationen, Stellungseinschätzung und dergleichen mehr beinhaltet."
}
}

View File

@ -1,10 +1,5 @@
{
"_id": "Msv0BWdwlNlF2EtU",
"_key": "!items!Msv0BWdwlNlF2EtU",
"type": "Skill",
"name": "Dolche",
"system": {
"gruppe": "Kampf",
"talent": "Hierzu gehören alle zum Stich (und so gut wie nicht zur Parade) geeigneten Klingenwaffen mit einer maximalen Gesamtlänge von einem halben Schritt also vom als Waffe eingesetzten Essmesser bis hin zum Langdolch, dessen größte Exemplare fast schon als Kurzschwert gelten können. Fast alle Dolche haben eine gerade, beidseitig angeschliffene Klinge."
}
}

Some files were not shown because too many files have changed in this diff Show More