Character Creation with Default Values is no longer possible (got to be but its not scope of MVP anyway).
Skills either from Compendia or Imported Entries can now be uniquely added to a Character. This approach will help us later with adding other Elements like Advantages (these need a "uniqueness" Attribute), Spells (always unique), Miracles (also always unique), Equipmentpull/47/head
parent
32031eb548
commit
1afdd483e6
|
|
@ -72,7 +72,7 @@ Hooks.once("init", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
Hooks.on('dropActorSheetData', (actor, sheet, data) => {
|
Hooks.on('dropActorSheetData', (actor, sheet, data) => {
|
||||||
CharacterSheet.onDroppedData(actor, sheet, data);
|
return CharacterSheet.onDroppedData(actor, sheet, data);
|
||||||
} )
|
} )
|
||||||
|
|
||||||
Hooks.once("ready", async function() {
|
Hooks.once("ready", async function() {
|
||||||
|
|
|
||||||
|
|
@ -1,41 +1,12 @@
|
||||||
import {Skill} from "../documents/skill.mjs";
|
import {Skill} from "../documents/skill.mjs";
|
||||||
|
import {SkillDataModel} from "./skill.mjs";
|
||||||
|
|
||||||
const {
|
const {
|
||||||
SchemaField, NumberField, StringField, EmbeddedDocumentField, DocumentIdField, ArrayField, ForeignDocumentField
|
SchemaField, NumberField, StringField, EmbeddedDocumentField, DocumentIdField, ArrayField, ForeignDocumentField
|
||||||
} = foundry.data.fields;
|
} = foundry.data.fields;
|
||||||
|
|
||||||
/**
|
|
||||||
* @extends {Map<string, Set<VornachteileDataModel>>}
|
|
||||||
*/
|
|
||||||
class SkillMap extends Map {
|
|
||||||
/** @inheritDoc */
|
|
||||||
get(key, { type }={}) {
|
|
||||||
const result = super.get(key);
|
|
||||||
if ( !result?.size || !type ) return result;
|
|
||||||
return result.filter(i => i.type === type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
|
|
||||||
/** @inheritDoc */
|
|
||||||
set(key, value) {
|
|
||||||
if ( !this.has(key) ) super.set(key, new Set());
|
|
||||||
this.get(key).add(value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel {
|
export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mapping of item identifiers to the items.
|
|
||||||
* @type {SkillMap<string, Set<VornachteileDataModel>>}
|
|
||||||
*/
|
|
||||||
skills = this.skills
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
return {
|
return {
|
||||||
name: new StringField(),
|
name: new StringField(),
|
||||||
|
|
@ -143,11 +114,7 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel {
|
||||||
auswahlen: new ArrayField(new StringField()),
|
auswahlen: new ArrayField(new StringField()),
|
||||||
})),
|
})),
|
||||||
|
|
||||||
talente: new ArrayField(new SchemaField({
|
talente: new ArrayField(new DocumentIdField(Item)),
|
||||||
talent: new DocumentIdField(Item),
|
|
||||||
taw: new NumberField({integer: true, required: true}),
|
|
||||||
})
|
|
||||||
),
|
|
||||||
zauber: new ArrayField(new SchemaField({
|
zauber: new ArrayField(new SchemaField({
|
||||||
talent: new DocumentIdField(),
|
talent: new DocumentIdField(),
|
||||||
zfw: new NumberField({integer: true, required: true}),
|
zfw: new NumberField({integer: true, required: true}),
|
||||||
|
|
@ -171,106 +138,8 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel {
|
||||||
super._initialize(options);
|
super._initialize(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds base skills according to the BRW to the given actor
|
|
||||||
* @param actor
|
|
||||||
* @returns {Promise<void>}
|
|
||||||
*/
|
|
||||||
async #createBaseSkills(actor) {
|
|
||||||
const compendiumOfSkills = await game.packs.get('DSA_4-1.talente-brw');
|
|
||||||
const talentsByName = [
|
|
||||||
"Athletik", "Klettern", "Körperbeherrschung", "Schleichen", "Schwimmen", "Selbstbeherrschung", "Sich Verstecken", "Singen", "Sinnenschärfe", "Tanzen", "Zechen",
|
|
||||||
"Menschenkenntnis", "Überreden",
|
|
||||||
"Fährtensuchen", "Orientierung", "Wildnisleben",
|
|
||||||
"Götter/Kulte", "Rechnen", "Sagen/Legenden",
|
|
||||||
"Heilkunde: Wunden", "Holzbearbeitung", "Kochen", "Lederverarbeitung", "Malen/Zeichnen", "Schneidern"
|
|
||||||
]
|
|
||||||
|
|
||||||
const talente = []
|
|
||||||
|
|
||||||
const mappedCompendiumItems = talentsByName.map( talentName => {
|
|
||||||
const talent = compendiumOfSkills.index.find( skill => skill.name === talentName)
|
|
||||||
return talent._id
|
|
||||||
})
|
|
||||||
|
|
||||||
for (const talentId of mappedCompendiumItems) {
|
|
||||||
const talent = await compendiumOfSkills.getDocument(talentId);
|
|
||||||
try {
|
|
||||||
const embeddedDocument = (await thisCharacter.createEmbeddedDocuments('Item', [talent]))[0]
|
|
||||||
if (embeddedDocument.type === "Skill") {
|
|
||||||
if (talent) {
|
|
||||||
talente.push({
|
|
||||||
taw: 0,
|
|
||||||
talent: embeddedDocument.id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`${talentId} not found in items`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
await actor.update({system: { talente: talente}})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the attributes of the given actor to their default values
|
|
||||||
* @param actor
|
|
||||||
* @returns {Promise<void>}
|
|
||||||
*/
|
|
||||||
async #setBaseAttributes(actor) {
|
|
||||||
const startEigenschaften = {
|
|
||||||
"mu": {
|
|
||||||
start: 10,
|
|
||||||
aktuell: 10,
|
|
||||||
mod: 0
|
|
||||||
},
|
|
||||||
"kl": {
|
|
||||||
start: 10,
|
|
||||||
aktuell: 10,
|
|
||||||
mod: 0
|
|
||||||
},
|
|
||||||
"in": {
|
|
||||||
start: 10,
|
|
||||||
aktuell: 10,
|
|
||||||
mod: 0
|
|
||||||
},
|
|
||||||
"ch": {
|
|
||||||
start: 10,
|
|
||||||
aktuell: 10,
|
|
||||||
mod: 0
|
|
||||||
},
|
|
||||||
"ff": {
|
|
||||||
start: 10,
|
|
||||||
aktuell: 10,
|
|
||||||
mod: 0
|
|
||||||
},
|
|
||||||
"ge": {
|
|
||||||
start: 10,
|
|
||||||
aktuell: 10,
|
|
||||||
mod: 0
|
|
||||||
},
|
|
||||||
"ko": {
|
|
||||||
start: 10,
|
|
||||||
aktuell: 10,
|
|
||||||
mod: 0
|
|
||||||
},
|
|
||||||
"kk": {
|
|
||||||
start: 10,
|
|
||||||
aktuell: 10,
|
|
||||||
mod: 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await actor.update({system: {attribute: startEigenschaften}})
|
|
||||||
}
|
|
||||||
|
|
||||||
async _onCreate(data, options, userId) {
|
async _onCreate(data, options, userId) {
|
||||||
const thisCharacter = await game.actors.getName(data.name);
|
|
||||||
|
|
||||||
await this.#createBaseSkills(thisCharacter)
|
|
||||||
await this.#setBaseAttributes(thisCharacter)
|
|
||||||
|
|
||||||
super._onCreate(data, options, userId);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ export class SkillDataModel extends BaseItem {
|
||||||
return {
|
return {
|
||||||
name: new StringField({ required: true }),
|
name: new StringField({ required: true }),
|
||||||
gruppe: new StringField({ required: true }),
|
gruppe: new StringField({ required: true }),
|
||||||
|
taw: new NumberField({ integer: true, initial: 0 }),
|
||||||
probe: new ArrayField(new StringField(), { exact: 3 }), // References one of the eight attributes by name
|
probe: new ArrayField(new StringField(), { exact: 3 }), // References one of the eight attributes by name
|
||||||
voraussetzung: new SchemaField({
|
voraussetzung: new SchemaField({
|
||||||
talent: new StringField({ model: SkillDataModel }),
|
talent: new StringField({ model: SkillDataModel }),
|
||||||
|
|
@ -86,5 +87,4 @@ export class SkillDataModel extends BaseItem {
|
||||||
patzer: patzerCounter === countToPatzer,
|
patzer: patzerCounter === countToPatzer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -41,4 +41,103 @@ export class Character extends Actor {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async addSkillFromCompendiumByNameToActor(talentName, actor) {
|
||||||
|
const compendiumOfSkills = game.packs.get('DSA_4-1.talente-brw');
|
||||||
|
const talentId = compendiumOfSkills.index.find( skill => skill.name === talentName)
|
||||||
|
let talentObject = {}
|
||||||
|
const talent = await compendiumOfSkills.getDocument(talentId);
|
||||||
|
try {
|
||||||
|
const embeddedDocument = (await actor.createEmbeddedDocuments('Item', [talent]))[0]
|
||||||
|
if (embeddedDocument.type === "Skill") {
|
||||||
|
if (talent) {
|
||||||
|
talentObject = {
|
||||||
|
taw: 0,
|
||||||
|
talent: embeddedDocument.id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`${talentName} not found in items`, error)
|
||||||
|
}
|
||||||
|
await actor.update({system: { talente: talentObject, ...actor.system.talente}})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds base skills according to the BRW to the given actor
|
||||||
|
* @param actor
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async #createBaseSkills(actor) {
|
||||||
|
const talentsByName = [
|
||||||
|
"Athletik", "Klettern", "Körperbeherrschung", "Schleichen", "Schwimmen", "Selbstbeherrschung", "Sich Verstecken", "Singen", "Sinnenschärfe", "Tanzen", "Zechen",
|
||||||
|
"Menschenkenntnis", "Überreden",
|
||||||
|
"Fährtensuchen", "Orientierung", "Wildnisleben",
|
||||||
|
"Götter/Kulte", "Rechnen", "Sagen/Legenden",
|
||||||
|
"Heilkunde: Wunden", "Holzbearbeitung", "Kochen", "Lederverarbeitung", "Malen/Zeichnen", "Schneidern"
|
||||||
|
]
|
||||||
|
|
||||||
|
const talente = []
|
||||||
|
|
||||||
|
talentsByName.forEach(talentName => {
|
||||||
|
|
||||||
|
this.addSkillFromCompendiumByNameToActor(
|
||||||
|
talentName,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
await actor.update({system: { talente: talente}})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the attributes of the given actor to their default values
|
||||||
|
* @param actor
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async #setBaseAttributes(actor) {
|
||||||
|
const startEigenschaften = {
|
||||||
|
"mu": {
|
||||||
|
start: 10,
|
||||||
|
aktuell: 10,
|
||||||
|
mod: 0
|
||||||
|
},
|
||||||
|
"kl": {
|
||||||
|
start: 10,
|
||||||
|
aktuell: 10,
|
||||||
|
mod: 0
|
||||||
|
},
|
||||||
|
"in": {
|
||||||
|
start: 10,
|
||||||
|
aktuell: 10,
|
||||||
|
mod: 0
|
||||||
|
},
|
||||||
|
"ch": {
|
||||||
|
start: 10,
|
||||||
|
aktuell: 10,
|
||||||
|
mod: 0
|
||||||
|
},
|
||||||
|
"ff": {
|
||||||
|
start: 10,
|
||||||
|
aktuell: 10,
|
||||||
|
mod: 0
|
||||||
|
},
|
||||||
|
"ge": {
|
||||||
|
start: 10,
|
||||||
|
aktuell: 10,
|
||||||
|
mod: 0
|
||||||
|
},
|
||||||
|
"ko": {
|
||||||
|
start: 10,
|
||||||
|
aktuell: 10,
|
||||||
|
mod: 0
|
||||||
|
},
|
||||||
|
"kk": {
|
||||||
|
start: 10,
|
||||||
|
aktuell: 10,
|
||||||
|
mod: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await actor.update({system: {attribute: startEigenschaften}})
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -39,25 +39,15 @@ export class CharacterSheet extends ActorSheet {
|
||||||
}
|
}
|
||||||
|
|
||||||
#addSkillsToContext(context) {
|
#addSkillsToContext(context) {
|
||||||
const actorSkills = {}
|
|
||||||
const actorData = context.data;
|
const actorData = context.data;
|
||||||
context.skills = {};
|
context.skills = {};
|
||||||
context.flatSkills = [];
|
context.flatSkills = [];
|
||||||
|
|
||||||
Object.values(actorData.items).forEach( (item) => {
|
Object.values(actorData.items).forEach( (item, index) => {
|
||||||
if (item.type === "Skill") {
|
if (item.type === "Skill") {
|
||||||
actorSkills[item._id] = item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( context.system.talente?.length >= 0) {
|
const talentGruppe = item.system.gruppe;
|
||||||
context.system.talente.forEach( ( { taw, talent }, index) => {
|
const eigenschaften = Object.values(item.system.probe);
|
||||||
if (actorSkills[talent]) {
|
|
||||||
const talentObjekt = actorSkills[talent];
|
|
||||||
if (talentObjekt.type === 'Skill') {
|
|
||||||
const talentGruppe = talentObjekt.system.gruppe;
|
|
||||||
const eigenschaften = Object.values(talentObjekt.system.probe);
|
|
||||||
const werte = [
|
const werte = [
|
||||||
{name: eigenschaften[0], value: this.prepareEigenschaftRoll(actorData, eigenschaften[0])},
|
{name: eigenschaften[0], value: this.prepareEigenschaftRoll(actorData, eigenschaften[0])},
|
||||||
{name: eigenschaften[1], value: this.prepareEigenschaftRoll(actorData, eigenschaften[1])},
|
{name: eigenschaften[1], value: this.prepareEigenschaftRoll(actorData, eigenschaften[1])},
|
||||||
|
|
@ -69,9 +59,9 @@ export class CharacterSheet extends ActorSheet {
|
||||||
const obj = {
|
const obj = {
|
||||||
type: "talent",
|
type: "talent",
|
||||||
gruppe: talentGruppe,
|
gruppe: talentGruppe,
|
||||||
name: talentObjekt.name,
|
name: item.name,
|
||||||
taw: "" + taw,
|
taw: "" + item.system.taw,
|
||||||
tawPath: `system.talente.${index}.taw`,
|
tawPath: `system.items.${index}.taw`,
|
||||||
werte,
|
werte,
|
||||||
rollEigenschaft1: werte[0].value,
|
rollEigenschaft1: werte[0].value,
|
||||||
rollEigenschaft2: werte[1].value,
|
rollEigenschaft2: werte[1].value,
|
||||||
|
|
@ -84,9 +74,8 @@ export class CharacterSheet extends ActorSheet {
|
||||||
context.skills[talentGruppe].push(obj);
|
context.skills[talentGruppe].push(obj);
|
||||||
context.flatSkills.push(obj);
|
context.flatSkills.push(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#addAdvantagesToContext(context) {
|
#addAdvantagesToContext(context) {
|
||||||
|
|
@ -298,88 +287,40 @@ export class CharacterSheet extends ActorSheet {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async #handleDroppedSkill(actor, data) {
|
#handleDroppedSkill(actor, skill) {
|
||||||
let alreadyInSet = false;
|
const array = Array.from(actor.items);
|
||||||
let previousTaw = 0;
|
for ( let i = 0; i < array.length; i++ ) {
|
||||||
const id = foundry.utils.parseUuid(data.uuid).id;
|
if (array[i].name === skill.name) {
|
||||||
|
return false;
|
||||||
const item = (await actor.createEmbeddedDocuments('Item', [await game.items.get(id)]))[0]
|
|
||||||
|
|
||||||
actor.system.talente.forEach(({taw, talent}) => {
|
|
||||||
if (talent) {
|
|
||||||
if (talent._id === item._id) {
|
|
||||||
alreadyInSet = talent;
|
|
||||||
previousTaw = taw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
const myContent = `TaW: <input id="taw" type="number" value="${previousTaw}" />`;
|
|
||||||
new Dialog({
|
|
||||||
title: `Talent ${item.name} ${alreadyInSet?'ersetzen':'hinzufügen'}`,
|
|
||||||
content: myContent,
|
|
||||||
buttons: {
|
|
||||||
button1: {
|
|
||||||
label: "hinzufügen",
|
|
||||||
callback: (html) => myCallback(html),
|
|
||||||
icon: `<i class="fas fa-check"></i>`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).render(true);
|
|
||||||
|
|
||||||
async function myCallback(html) {
|
|
||||||
const taw = html.find("input#taw").val();
|
|
||||||
|
|
||||||
let index = actor.system.talente.findIndex( predicate => predicate.talent && predicate.talent._id === alreadyInSet._id )
|
|
||||||
let sorted = [];
|
|
||||||
if (alreadyInSet) {
|
|
||||||
actor.system.talente[index].taw = taw;
|
|
||||||
sorted = actor.system.talente;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
const newItem = {
|
|
||||||
taw: taw,
|
|
||||||
talent: {_id: item._id, name: item.name}
|
|
||||||
}
|
|
||||||
console.log(newItem, await game.items.get(item._id))
|
|
||||||
sorted = [newItem, ...actor.system.talente].sort((a, b) => {
|
|
||||||
|
|
||||||
return a.talent.name.localeCompare(b.talent.name)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const serialised = sorted.map(({taw, talent}) => {
|
|
||||||
return {
|
|
||||||
taw: taw,
|
|
||||||
talent: talent._id
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
await actor.update({
|
|
||||||
system: {
|
|
||||||
talente: [
|
|
||||||
|
|
||||||
...serialised
|
|
||||||
]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
ui.notifications.info(`Talent ${item.name} auf TaW ${taw} hinzugefügt`);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getElementByName(collection, id) {
|
||||||
|
const array = Array.from(collection);
|
||||||
|
for (const element of array) {
|
||||||
|
if (element._id === id) {
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static onDroppedData(actor, characterSheet, data) {
|
static onDroppedData(actor, characterSheet, data) {
|
||||||
const item = game.items.get(foundry.utils.parseUuid(data.uuid).id)
|
const uuid = foundry.utils.parseUuid(data.uuid);
|
||||||
|
const collection = uuid.collection.index ?? uuid.collection;
|
||||||
switch (item.type) {
|
const document = CharacterSheet.getElementByName(collection, uuid.id);
|
||||||
|
const {
|
||||||
|
name,
|
||||||
|
type
|
||||||
|
} = document
|
||||||
|
console.log(name, type)
|
||||||
|
switch (type) {
|
||||||
case "Skill":
|
case "Skill":
|
||||||
characterSheet.#handleDroppedSkill(actor, data);
|
return characterSheet.#handleDroppedSkill(actor, document); // on false cancel this whole operation
|
||||||
default:
|
default:
|
||||||
console.log(item, item.type);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// maybe dont
|
|
||||||
actor.items.clear()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,22 @@ function calculateBirthdate(json) {
|
||||||
return `${day}. ${month} ${year} BF`
|
return `${day}. ${month} ${year} BF`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mapSkills(rawJson) {
|
||||||
|
let talents = []
|
||||||
|
for (let talent in held.talentliste.talent) {
|
||||||
|
talent = held.talentliste.talent[talent]
|
||||||
|
let talentItem = game.items.getName(talent.name)
|
||||||
|
if (talentItem) {
|
||||||
|
let talentJson = {
|
||||||
|
talent: talentItem,
|
||||||
|
taw: talent.value,
|
||||||
|
}
|
||||||
|
talents.push(talentJson)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return talents
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* parses a json into a fitting character-json
|
* parses a json into a fitting character-json
|
||||||
* @param rawJson the json parsed from the Helden-Software XML
|
* @param rawJson the json parsed from the Helden-Software XML
|
||||||
|
|
@ -248,19 +264,8 @@ function mapRawJson(rawJson) {
|
||||||
}
|
}
|
||||||
json.sonderfertigkeiten = specialAbilities
|
json.sonderfertigkeiten = specialAbilities
|
||||||
json.liturgien = liturgies
|
json.liturgien = liturgies
|
||||||
let talents = []
|
|
||||||
for (let talent in held.talentliste.talent) {
|
json.talente = mapSkills(rawJson)
|
||||||
talent = held.talentliste.talent[talent]
|
|
||||||
let talentItem = game.items.getName(talent.name)
|
|
||||||
if (talentItem) {
|
|
||||||
let talentJson = {
|
|
||||||
talent: talentItem,
|
|
||||||
taw: talent.value,
|
|
||||||
}
|
|
||||||
talents.push(talentJson)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
json.talente = talents
|
|
||||||
let spells = []
|
let spells = []
|
||||||
/*for (let spell in held.zauberliste.zauber) {
|
/*for (let spell in held.zauberliste.zauber) {
|
||||||
spell = held.zauberliste.zauber[spell]
|
spell = held.zauberliste.zauber[spell]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue