Fertigstellung XML-Import #13
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><?xml-stylesheet type="text/xsl" href="helden.xsl"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?><?xml-stylesheet type="text/xsl" href="helden.xsl"?>
|
||||||
<helden Version="5.5.3">
|
<helden Version="5.5.3">
|
||||||
<held key="1758727714759" name="Travin Walroder" stand="1758728185936">
|
<held key="1758727714759" name="Travin Walroder" stand="1758827726594">
|
||||||
<mods/>
|
<mods/>
|
||||||
<basis>
|
<basis>
|
||||||
<geschlecht name="männlich"/>
|
<geschlecht name="männlich"/>
|
||||||
|
|
@ -13,15 +13,17 @@
|
||||||
</settings>
|
</settings>
|
||||||
<rasse name="helden.model.rasse.Mittellaender" string="Mittelländer">
|
<rasse name="helden.model.rasse.Mittellaender" string="Mittelländer">
|
||||||
<groesse gewicht="76" value="176"/>
|
<groesse gewicht="76" value="176"/>
|
||||||
<aussehen alter="19" augenfarbe="blau" aussehentext0="" aussehentext1="" aussehentext2=""
|
<aussehen alter="19" augenfarbe="blau" aussehentext0="Sieht man"
|
||||||
aussehentext3="" familietext0="" familietext1="" familietext2="" familietext3=""
|
aussehentext1="Kann man nicht verfehlen" aussehentext2="Ist vorhanden"
|
||||||
familietext4="" familietext5="" gbjahr="1003" gbmonat="2" gbtag="11" gprest="26" gpstart="160"
|
aussehentext3="Glitzert ein wenig" familietext0="Mama" familietext1="Papa"
|
||||||
haarfarbe="weißblond" kalender="Bosparans Fall" stand="" titel=""/>
|
familietext2="Schwester" familietext3="Bruder" familietext4="Oma" familietext5="Opa"
|
||||||
|
gbjahr="1003" gbmonat="13" gbtag="5" gprest="26" gpstart="160" haarfarbe="weißblond"
|
||||||
|
kalender="Bosparans Fall" stand="Graf" titel="von und zu"/>
|
||||||
</rasse>
|
</rasse>
|
||||||
<kultur name="helden.model.kultur.Garetien" string="Mittelländische Städte"/>
|
<kultur name="helden.model.kultur.Garetien" string="Mittelländische Städte"/>
|
||||||
<ausbildungen>
|
<ausbildungen>
|
||||||
<ausbildung art="Hauptprofession" name="helden.model.profession.Magier"
|
<ausbildung art="Hauptprofession" name="helden.model.profession.Magier"
|
||||||
string="Akademie der Magischen Rüstung zu Gareth " tarnidentitaet="">
|
string="Akademie der Magischen Rüstung zu Gareth " tarnidentitaet="Depp vom Dienst">
|
||||||
<variante name="Akademie der Magischen Rüstung zu Gareth "/>
|
<variante name="Akademie der Magischen Rüstung zu Gareth "/>
|
||||||
</ausbildung>
|
</ausbildung>
|
||||||
<ausbildung art="Spaetweihe" name="helden.model.profession.Geweihter"
|
<ausbildung art="Spaetweihe" name="helden.model.profession.Geweihter"
|
||||||
|
|
@ -34,7 +36,7 @@
|
||||||
notiz7="" notiz8="" notiz9=""/>
|
notiz7="" notiz8="" notiz9=""/>
|
||||||
<portraet value=""/>
|
<portraet value=""/>
|
||||||
<abenteuerpunkte value="15000"/>
|
<abenteuerpunkte value="15000"/>
|
||||||
<freieabenteuerpunkte value="6119"/>
|
<freieabenteuerpunkte value="5632"/>
|
||||||
<gilde name="weiß"/>
|
<gilde name="weiß"/>
|
||||||
</basis>
|
</basis>
|
||||||
<eigenschaften>
|
<eigenschaften>
|
||||||
|
|
@ -73,6 +75,13 @@
|
||||||
<auswahl name="Hesinde"/>
|
<auswahl name="Hesinde"/>
|
||||||
</sonderfertigkeit>
|
</sonderfertigkeit>
|
||||||
<sonderfertigkeit name="Astrale Meditation"/>
|
<sonderfertigkeit name="Astrale Meditation"/>
|
||||||
|
<sonderfertigkeit name="Berufsgeheimnis">
|
||||||
|
<auswahl>
|
||||||
|
<wahl position="0" value="Ackerbau"/>
|
||||||
|
<wahl position="1" value="Abrichten"/>
|
||||||
|
<wahl position="2" value="Knüppel auf den Kopp"/>
|
||||||
|
</auswahl>
|
||||||
|
</sonderfertigkeit>
|
||||||
<sonderfertigkeit name="Große Meditation"/>
|
<sonderfertigkeit name="Große Meditation"/>
|
||||||
<sonderfertigkeit name="Kulturkunde">
|
<sonderfertigkeit name="Kulturkunde">
|
||||||
<kultur name="Mittelreich"/>
|
<kultur name="Mittelreich"/>
|
||||||
|
|
@ -90,6 +99,13 @@
|
||||||
<sonderfertigkeit name="Ritualkenntnis: Gildenmagie"/>
|
<sonderfertigkeit name="Ritualkenntnis: Gildenmagie"/>
|
||||||
<sonderfertigkeit name="Spätweihe Alveranische Gottheit"/>
|
<sonderfertigkeit name="Spätweihe Alveranische Gottheit"/>
|
||||||
<sonderfertigkeit name="Stabzauber: Bindung"/>
|
<sonderfertigkeit name="Stabzauber: Bindung"/>
|
||||||
|
<sonderfertigkeit name="Wahrer Name: Dschinn">
|
||||||
|
<auswahl>
|
||||||
|
<wahl position="0" value="Luft"/>
|
||||||
|
<wahl position="1" value="1"/>
|
||||||
|
<wahl position="2" value="Rüdiger"/>
|
||||||
|
</auswahl>
|
||||||
|
</sonderfertigkeit>
|
||||||
</sf>
|
</sf>
|
||||||
<ereignisse>
|
<ereignisse>
|
||||||
<ereignis obj="max GP für Helden: 160" text="EINSTELLUNG" time="1758727716048" version="HS 5.5.3"/>
|
<ereignis obj="max GP für Helden: 160" text="EINSTELLUNG" time="1758727716048" version="HS 5.5.3"/>
|
||||||
|
|
@ -257,6 +273,59 @@
|
||||||
text="Sonderfertigkeit hinzugefügt" time="1758728180962" version="HS 5.5.3"/>
|
text="Sonderfertigkeit hinzugefügt" time="1758728180962" version="HS 5.5.3"/>
|
||||||
<ereignis Abenteuerpunkte="-250" Karmaenergie="-1" obj="Liturgie: Göttliche Strafe (V)"
|
<ereignis Abenteuerpunkte="-250" Karmaenergie="-1" obj="Liturgie: Göttliche Strafe (V)"
|
||||||
text="Sonderfertigkeit hinzugefügt" time="1758728185936" version="HS 5.5.3"/>
|
text="Sonderfertigkeit hinzugefügt" time="1758728185936" version="HS 5.5.3"/>
|
||||||
|
<ereignis kommentar="[BROKENSIG, EDITOREINGEGEBEN]"
|
||||||
|
obj="Held wurde extern verändert. Änderungskontrolle wieder aktiviert." text="Änderungskontrolle"
|
||||||
|
time="1758822738691" version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-4" Alt="1" Info="Gegenseitiges Lehren" Neu="2" obj="Ackerbau"
|
||||||
|
text="Talent steigern" time="1758827653479" version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-6" Alt="2" Info="Gegenseitiges Lehren" Neu="3" obj="Ackerbau"
|
||||||
|
text="Talent steigern" time="1758827653657" version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-8" Alt="3" Info="Gegenseitiges Lehren" Neu="4" obj="Ackerbau"
|
||||||
|
text="Talent steigern" time="1758827653813" version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-11" Alt="4" Info="Gegenseitiges Lehren" Neu="5" obj="Ackerbau"
|
||||||
|
text="Talent steigern" time="1758827653954" version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-14" Alt="5" Info="Gegenseitiges Lehren" Neu="6" obj="Ackerbau"
|
||||||
|
text="Talent steigern" time="1758827654121" version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-17" Alt="6" Info="Gegenseitiges Lehren" Neu="7" obj="Ackerbau"
|
||||||
|
text="Talent steigern" time="1758827654690" version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-11" Alt="4" Info="Gegenseitiges Lehren" Neu="5" obj="Alchimie"
|
||||||
|
text="Talent steigern" time="1758827656137" version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-19" Alt="7" Info="Gegenseitiges Lehren" Neu="8" obj="Ackerbau"
|
||||||
|
text="Talent steigern" time="1758827657421" version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-22" Alt="8" Info="Gegenseitiges Lehren" Neu="9" obj="Ackerbau"
|
||||||
|
text="Talent steigern" time="1758827657884" version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-25" Alt="9" Info="Gegenseitiges Lehren" Neu="10" obj="Ackerbau"
|
||||||
|
text="Talent steigern" time="1758827658047" version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-28" Alt="10" Info="Gegenseitiges Lehren" Neu="11" obj="Ackerbau"
|
||||||
|
text="Talent steigern" time="1758827658217" version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-32" Alt="11" Info="Gegenseitiges Lehren" Neu="12" obj="Ackerbau"
|
||||||
|
text="Talent steigern" time="1758827658385" version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-35" Alt="12" Info="Gegenseitiges Lehren" Neu="13" obj="Ackerbau"
|
||||||
|
text="Talent steigern" time="1758827658554" version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-38" Alt="13" Info="Gegenseitiges Lehren" Neu="14" obj="Ackerbau"
|
||||||
|
text="Talent steigern" time="1758827658729" version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-41" Alt="14" Info="Gegenseitiges Lehren" Neu="15" obj="Ackerbau"
|
||||||
|
text="Talent steigern" time="1758827659093" version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-10" Neu="0" obj="Abrichten" text="Talent aktivieren" time="1758827670806"
|
||||||
|
version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-2" Alt="0" Info="Gegenseitiges Lehren" Neu="1" obj="Abrichten"
|
||||||
|
text="Talent steigern" time="1758827675626" version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-4" Alt="1" Info="Gegenseitiges Lehren" Neu="2" obj="Abrichten"
|
||||||
|
text="Talent steigern" time="1758827675769" version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-6" Alt="2" Info="Gegenseitiges Lehren" Neu="3" obj="Abrichten"
|
||||||
|
text="Talent steigern" time="1758827675936" version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-8" Alt="3" Info="Gegenseitiges Lehren" Neu="4" obj="Abrichten"
|
||||||
|
text="Talent steigern" time="1758827676096" version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-11" Alt="4" Info="Gegenseitiges Lehren" Neu="5" obj="Abrichten"
|
||||||
|
text="Talent steigern" time="1758827676247" version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-14" Alt="5" Info="Gegenseitiges Lehren" Neu="6" obj="Abrichten"
|
||||||
|
text="Talent steigern" time="1758827676400" version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-17" Alt="6" Info="Gegenseitiges Lehren" Neu="7" obj="Abrichten"
|
||||||
|
text="Talent steigern" time="1758827676561" version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-100" obj="Berufsgeheimnis (Ackerbau; Abrichten; Knüppel auf den Kopp)"
|
||||||
|
text="Sonderfertigkeit hinzugefügt" time="1758827690491" version="HS 5.5.3"/>
|
||||||
|
<ereignis Abenteuerpunkte="-4" obj="Wahrer Name: Dschinn (Luft Q1 Rüdiger)"
|
||||||
|
text="Sonderfertigkeit hinzugefügt" time="1758827726594" version="HS 5.5.3"/>
|
||||||
</ereignisse>
|
</ereignisse>
|
||||||
<talentliste>
|
<talentliste>
|
||||||
<talent lernmethode="Gegenseitiges Lehren" name="Armbrust" probe=" (GE/FF/KK)" value="1"/>
|
<talent lernmethode="Gegenseitiges Lehren" name="Armbrust" probe=" (GE/FF/KK)" value="1"/>
|
||||||
|
|
@ -320,8 +389,9 @@
|
||||||
value="6"/>
|
value="6"/>
|
||||||
<talent k="16" lernmethode="Gegenseitiges Lehren" name="Lesen/Schreiben Urtulamidya" probe=" (KL/KL/FF)"
|
<talent k="16" lernmethode="Gegenseitiges Lehren" name="Lesen/Schreiben Urtulamidya" probe=" (KL/KL/FF)"
|
||||||
value="6"/>
|
value="6"/>
|
||||||
<talent lernmethode="Gegenseitiges Lehren" name="Ackerbau" probe=" (IN/FF/KO)" value="1"/>
|
<talent lernmethode="Gegenseitiges Lehren" name="Abrichten" probe=" (MU/IN/CH)" value="7"/>
|
||||||
<talent lernmethode="Gegenseitiges Lehren" name="Alchimie" probe=" (MU/KL/FF)" value="4"/>
|
<talent lernmethode="Gegenseitiges Lehren" name="Ackerbau" probe=" (IN/FF/KO)" value="15"/>
|
||||||
|
<talent lernmethode="Gegenseitiges Lehren" name="Alchimie" probe=" (MU/KL/FF)" value="5"/>
|
||||||
<talent lernmethode="Gegenseitiges Lehren" name="Heilkunde: Gift" probe=" (MU/KL/IN)" value="4"/>
|
<talent lernmethode="Gegenseitiges Lehren" name="Heilkunde: Gift" probe=" (MU/KL/IN)" value="4"/>
|
||||||
<talent lernmethode="Gegenseitiges Lehren" name="Heilkunde: Wunden" probe=" (KL/CH/FF)" value="4"/>
|
<talent lernmethode="Gegenseitiges Lehren" name="Heilkunde: Wunden" probe=" (KL/CH/FF)" value="4"/>
|
||||||
<talent lernmethode="Gegenseitiges Lehren" name="Holzbearbeitung" probe=" (KL/FF/KK)" value="0"/>
|
<talent lernmethode="Gegenseitiges Lehren" name="Holzbearbeitung" probe=" (KL/FF/KK)" value="0"/>
|
||||||
|
|
@ -506,6 +576,7 @@
|
||||||
</gegenstände>
|
</gegenstände>
|
||||||
<BoniWaffenlos/>
|
<BoniWaffenlos/>
|
||||||
<kommentare>
|
<kommentare>
|
||||||
|
<kommentar key="Ortskenntnis (Stadtteil/Kleinstadt)" kommentar="Andergast"/>
|
||||||
<sfInfos dauer="" kosten="" probe="" sf="" sfname="Liturgie: Argelions bannende Hand" wirkung=""/>
|
<sfInfos dauer="" kosten="" probe="" sf="" sfname="Liturgie: Argelions bannende Hand" wirkung=""/>
|
||||||
<sfInfos dauer="" kosten="" probe="" sf="" sfname="Liturgie: Cereborns Handreichung (Handwerkssegen)"
|
<sfInfos dauer="" kosten="" probe="" sf="" sfname="Liturgie: Cereborns Handreichung (Handwerkssegen)"
|
||||||
wirkung=""/>
|
wirkung=""/>
|
||||||
|
|
@ -542,10 +613,10 @@
|
||||||
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
||||||
</Transforms>
|
</Transforms>
|
||||||
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
||||||
<DigestValue>D/lXw741ikWhJ+dIE/eCcUgT5vw=</DigestValue>
|
<DigestValue>a1RMsniSGUvFk5vUM6faRb5HF7M=</DigestValue>
|
||||||
</Reference>
|
</Reference>
|
||||||
</SignedInfo>
|
</SignedInfo>
|
||||||
<SignatureValue>Yo5RyWxO8N8Z0ReQlPhESaEjbpFUFTANob25mAXlFTH0eCBano63WQ==</SignatureValue>
|
<SignatureValue>IoH2tMVRNhVL5zF5VrhsiYRdosA0GopNsJMf4tFpYVi5yPW6RhGqNQ==</SignatureValue>
|
||||||
<KeyInfo>
|
<KeyInfo>
|
||||||
<KeyValue>
|
<KeyValue>
|
||||||
<DSAKeyValue>
|
<DSAKeyValue>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import { PlayerCharacterDataModel } from "./module/data/character.mjs";
|
import {PlayerCharacterDataModel} from "./module/data/character.mjs";
|
||||||
import { SkillSheet } from "./module/sheets/skillSheet.mjs";
|
import { SkillSheet } from "./module/sheets/skillSheet.mjs";
|
||||||
import { SpellSheet } from "./module/sheets/spellSheet.mjs";
|
import { SpellSheet } from "./module/sheets/spellSheet.mjs";
|
||||||
import { CharacterSheet } from "./module/sheets/characterSheet.mjs";
|
|
||||||
import { SkillDataModel } from "./module/data/skill.mjs";
|
import { SkillDataModel } from "./module/data/skill.mjs";
|
||||||
import { SpellDataModel } from "./module/data/spell.mjs";
|
import { SpellDataModel } from "./module/data/spell.mjs";
|
||||||
import { Character } from "./module/documents/character.mjs";
|
import { Character } from "./module/documents/character.mjs";
|
||||||
|
import { CharacterSheet } from "./module/sheets/characterSheet.mjs";
|
||||||
|
|
||||||
Hooks.once("init", () => {
|
Hooks.once("init", () => {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,5 @@
|
||||||
import {SkillDataModel} from "./skill.mjs";
|
|
||||||
import {SpellDataModel} from "./spell.mjs";
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
SchemaField, NumberField, StringField, ArrayField, BooleanField, ForeignDocumentField
|
SchemaField, NumberField, StringField, ArrayField, ForeignDocumentField
|
||||||
} = foundry.data.fields;
|
} = foundry.data.fields;
|
||||||
|
|
||||||
export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel {
|
export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel {
|
||||||
|
|
@ -13,7 +10,7 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel {
|
||||||
meta: new SchemaField({
|
meta: new SchemaField({
|
||||||
spezies: new StringField(),
|
spezies: new StringField(),
|
||||||
kultur: new StringField(),
|
kultur: new StringField(),
|
||||||
profession: new StringField(),
|
professions: new ArrayField(new StringField()),
|
||||||
geschlecht: new StringField(),
|
geschlecht: new StringField(),
|
||||||
haarfarbe: new StringField(),
|
haarfarbe: new StringField(),
|
||||||
groesse: new NumberField({ required: true, integer: false }),
|
groesse: new NumberField({ required: true, integer: false }),
|
||||||
|
|
@ -21,31 +18,120 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel {
|
||||||
geburtstag: new StringField(),
|
geburtstag: new StringField(),
|
||||||
alter: new NumberField({ required: true, integer: true }),
|
alter: new NumberField({ required: true, integer: true }),
|
||||||
gewicht: new NumberField({ required: true, integer: true }),
|
gewicht: new NumberField({ required: true, integer: true }),
|
||||||
|
aussehen: new ArrayField(new StringField()),
|
||||||
|
familie: new ArrayField(new StringField()),
|
||||||
|
titel: new StringField(),
|
||||||
|
stand: new StringField(),
|
||||||
}),
|
}),
|
||||||
attribute: new SchemaField({
|
attribute: new SchemaField({
|
||||||
mu: new NumberField({ required: true, integer: true }),
|
mu: new SchemaField({
|
||||||
kl: new NumberField({ required: true, integer: true }),
|
start: new NumberField({ required: true, integer: true }),
|
||||||
in: new NumberField({ required: true, integer: true }),
|
aktuell: new NumberField({ required: true, integer: true }),
|
||||||
ch: new NumberField({ required: true, integer: true }),
|
mod: new NumberField({ required: true, integer: true }),
|
||||||
ff: new NumberField({ required: true, integer: true }),
|
}),
|
||||||
ge: new NumberField({ required: true, integer: true }),
|
kl: new SchemaField({
|
||||||
ko: new NumberField({ required: true, integer: true }),
|
start: new NumberField({ required: true, integer: true }),
|
||||||
kk: new NumberField({ required: true, integer: true }),
|
aktuell: new NumberField({ required: true, integer: true }),
|
||||||
mr: new NumberField({ required: true, integer: true }),
|
mod: new NumberField({ required: true, integer: true }),
|
||||||
lep: new NumberField({ required: true, integer: true }),
|
}),
|
||||||
aup: new NumberField({ required: true, integer: true }),
|
in: new SchemaField({
|
||||||
asp: new NumberField({ required: false, integer: true }),
|
start: new NumberField({ required: true, integer: true }),
|
||||||
kap: new NumberField({ required: false, integer: true }),
|
aktuell: new NumberField({ required: true, integer: true }),
|
||||||
at: new NumberField({ required: true, integer: true }),
|
mod: new NumberField({ required: true, integer: true }),
|
||||||
pa: new NumberField({ required: true, integer: true }),
|
}),
|
||||||
fk: new NumberField({ required: true, integer: true }),
|
ch: new SchemaField({
|
||||||
ini: new NumberField({ required: true, integer: true }),
|
start: new NumberField({ required: true, integer: true }),
|
||||||
so: new NumberField({ required: true, integer: true }),
|
aktuell: new NumberField({ required: true, integer: true }),
|
||||||
|
mod: new NumberField({ required: true, integer: true }),
|
||||||
|
}),
|
||||||
|
ff: new SchemaField({
|
||||||
|
start: new NumberField({ required: true, integer: true }),
|
||||||
|
aktuell: new NumberField({ required: true, integer: true }),
|
||||||
|
mod: new NumberField({ required: true, integer: true }),
|
||||||
|
}),
|
||||||
|
ge: new SchemaField({
|
||||||
|
start: new NumberField({ required: true, integer: true }),
|
||||||
|
aktuell: new NumberField({ required: true, integer: true }),
|
||||||
|
mod: new NumberField({ required: true, integer: true }),
|
||||||
|
}),
|
||||||
|
ko: new SchemaField({
|
||||||
|
start: new NumberField({ required: true, integer: true }),
|
||||||
|
aktuell: new NumberField({ required: true, integer: true }),
|
||||||
|
mod: new NumberField({ required: true, integer: true }),
|
||||||
|
}),
|
||||||
|
kk: new SchemaField({
|
||||||
|
start: new NumberField({ required: true, integer: true }),
|
||||||
|
aktuell: new NumberField({ required: true, integer: true }),
|
||||||
|
mod: new NumberField({ required: true, integer: true }),
|
||||||
|
}),
|
||||||
|
mr: new SchemaField({
|
||||||
|
mod: new NumberField({ required: true, integer: true }),
|
||||||
|
}),
|
||||||
|
lep: new SchemaField({
|
||||||
|
mod: new NumberField({ required: true, integer: true }),
|
||||||
|
}),
|
||||||
|
aup: new SchemaField({
|
||||||
|
mod: new NumberField({ required: true, integer: true }),
|
||||||
|
}),
|
||||||
|
asp: new SchemaField({
|
||||||
|
mod: new NumberField({ required: true, integer: true }),
|
||||||
|
}),
|
||||||
|
kap: new SchemaField({
|
||||||
|
mod: new NumberField({ required: true, integer: true }),
|
||||||
|
}),
|
||||||
|
at: new SchemaField({
|
||||||
|
aktuell: new NumberField({ required: true, integer: true }),
|
||||||
|
mod: new NumberField({ required: true, integer: true }),
|
||||||
|
}),
|
||||||
|
pa: new SchemaField({
|
||||||
|
aktuell: new NumberField({ required: true, integer: true }),
|
||||||
|
mod: new NumberField({ required: true, integer: true }),
|
||||||
|
}),
|
||||||
|
fk: new SchemaField({
|
||||||
|
aktuell: new NumberField({ required: true, integer: true }),
|
||||||
|
mod: new NumberField({ required: true, integer: true }),
|
||||||
|
}),
|
||||||
|
ini: new SchemaField({
|
||||||
|
aktuell: new NumberField({ required: true, integer: true }),
|
||||||
|
mod: new NumberField({ required: true, integer: true }),
|
||||||
|
}),
|
||||||
|
so: new SchemaField({
|
||||||
|
start: new NumberField({ required: true, integer: true }),
|
||||||
|
aktuell: new NumberField({ required: true, integer: true }),
|
||||||
|
mod: new NumberField({ required: true, integer: true }),
|
||||||
|
}),
|
||||||
gilde: new StringField(),
|
gilde: new StringField(),
|
||||||
}),
|
}),
|
||||||
talente: new ArrayField ( new SchemaField(
|
vornachteile: new ArrayField(new SchemaField({
|
||||||
{taw: new NumberField(), talent: new ForeignDocumentField(Item) })),
|
name: new StringField(),
|
||||||
zauber: new ArrayField ( new ForeignDocumentField(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 SchemaField({
|
||||||
|
talent: new ForeignDocumentField(Item),
|
||||||
|
taw: new NumberField({integer: true, required: true}),
|
||||||
|
})
|
||||||
|
),
|
||||||
|
zauber: new ArrayField(new SchemaField({
|
||||||
|
talent: new ForeignDocumentField(Item),
|
||||||
|
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 }),
|
||||||
|
pa: new NumberField({ required: true, integer: true }),
|
||||||
|
})),
|
||||||
|
notizen: new ArrayField(new SchemaField({
|
||||||
|
key: new StringField(),
|
||||||
|
notiz: new StringField(),
|
||||||
|
})),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,16 @@
|
||||||
|
import {importCharacter} from "../xml-import/xml-import.mjs";
|
||||||
|
|
||||||
export class Character extends Actor {
|
export class Character extends Actor {
|
||||||
|
|
||||||
|
import() {
|
||||||
|
let input = document.createElement('input')
|
||||||
|
input.type = 'file'
|
||||||
|
input.accept = '.xml'
|
||||||
|
input.onchange = e => {
|
||||||
|
importCharacter(this.id, e.target.files[0])
|
||||||
|
}
|
||||||
|
input.click()
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Augment the basic Item data model with additional dynamic data.
|
* Augment the basic Item data model with additional dynamic data.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -38,42 +38,42 @@ export class CharacterSheet extends ActorSheet {
|
||||||
{
|
{
|
||||||
eigenschaft: "mu",
|
eigenschaft: "mu",
|
||||||
name: "Mut",
|
name: "Mut",
|
||||||
wert: actorData.system.attribute.mu ?? 0,
|
wert: actorData.system.attribute.mu.aktuell ?? 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
eigenschaft: "kl",
|
eigenschaft: "kl",
|
||||||
name: "Klugheit",
|
name: "Klugheit",
|
||||||
wert: actorData.system.attribute.kl ?? 0,
|
wert: actorData.system.attribute.kl.aktuell ?? 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
eigenschaft: "in",
|
eigenschaft: "in",
|
||||||
name: "Intuition",
|
name: "Intuition",
|
||||||
wert: actorData.system.attribute.in ?? 0,
|
wert: actorData.system.attribute.in.aktuell ?? 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
eigenschaft: "ch",
|
eigenschaft: "ch",
|
||||||
name: "Charisma",
|
name: "Charisma",
|
||||||
wert: actorData.system.attribute.ch ?? 0,
|
wert: actorData.system.attribute.ch.aktuell ?? 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
eigenschaft: "ff",
|
eigenschaft: "ff",
|
||||||
name: "Fingerfertigkeit",
|
name: "Fingerfertigkeit",
|
||||||
wert: actorData.system.attribute.ff ?? 0,
|
wert: actorData.system.attribute.ff.aktuell ?? 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
eigenschaft: "ge",
|
eigenschaft: "ge",
|
||||||
name: "Geschicklichkeit",
|
name: "Geschicklichkeit",
|
||||||
wert: actorData.system.attribute.ge ?? 0,
|
wert: actorData.system.attribute.ge.aktuell ?? 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
eigenschaft: "ko",
|
eigenschaft: "ko",
|
||||||
name: "Konstitution",
|
name: "Konstitution",
|
||||||
wert: actorData.system.attribute.ko ?? 0,
|
wert: actorData.system.attribute.ko.aktuell ?? 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
eigenschaft: "kk",
|
eigenschaft: "kk",
|
||||||
name: "Körperkraft",
|
name: "Körperkraft",
|
||||||
wert: actorData.system.attribute.kk ?? 0,
|
wert: actorData.system.attribute.kk.aktuell ?? 0,
|
||||||
},
|
},
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,340 @@
|
||||||
|
let months = [
|
||||||
|
"Praios",
|
||||||
|
"Rondra",
|
||||||
|
"Efferd",
|
||||||
|
"Travia",
|
||||||
|
"Boron",
|
||||||
|
"Hesinde",
|
||||||
|
"Firun",
|
||||||
|
"Tsa",
|
||||||
|
"Phex",
|
||||||
|
"Peraine",
|
||||||
|
"Ingerimm",
|
||||||
|
"Rahja",
|
||||||
|
"Namenloser Tag"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Imports a character from a file created in the tool Helden-Software
|
||||||
|
* @param actorId the actor-id of the character
|
||||||
|
* @param file the file from which the character should be imported
|
||||||
|
*/
|
||||||
|
export async function importCharacter(actorId, file) {
|
||||||
|
let actor = game.actors.get(actorId)
|
||||||
|
let xmlString = await parseFileToString(file)
|
||||||
|
let domParser = new DOMParser()
|
||||||
|
let dom = domParser.parseFromString(xmlString, 'application/xml')
|
||||||
|
|
||||||
|
let rawJson = getJsonFromXML(dom)
|
||||||
|
let characterJson = mapRawJson(rawJson)
|
||||||
|
|
||||||
|
actor.update(characterJson)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param dom the XML-Dom from which the json should be extracted
|
||||||
|
* @returns {{}} the json parsed from the xml
|
||||||
|
*/
|
||||||
|
function getJsonFromXML(dom) {
|
||||||
|
let children = [...dom.children];
|
||||||
|
|
||||||
|
// initializing object to be returned.
|
||||||
|
let jsonResult = {};
|
||||||
|
|
||||||
|
let attributes = dom.attributes ? dom.attributes : []
|
||||||
|
for (let attribute of attributes) {
|
||||||
|
jsonResult[attribute.name] = attribute.value
|
||||||
|
}
|
||||||
|
|
||||||
|
if (children.length) {
|
||||||
|
for (let child of children) {
|
||||||
|
|
||||||
|
// checking is child has siblings of same name.
|
||||||
|
let childIsArray = children.filter(eachChild => eachChild.nodeName === child.nodeName).length > 1;
|
||||||
|
|
||||||
|
// if child is array, save the values as array, else as strings.
|
||||||
|
if (childIsArray) {
|
||||||
|
if (jsonResult[child.nodeName] === undefined) {
|
||||||
|
jsonResult[child.nodeName] = [getJsonFromXML(child)];
|
||||||
|
} else {
|
||||||
|
jsonResult[child.nodeName].push(getJsonFromXML(child));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
jsonResult[child.nodeName] = getJsonFromXML(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gets the text content of a file
|
||||||
|
* @param file the file with the desired content
|
||||||
|
* @returns {Promise<String>} a promise that returns the string contents of the file
|
||||||
|
*/
|
||||||
|
async function parseFileToString(file) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let reader = new FileReader()
|
||||||
|
reader.readAsText(file, "utf-8")
|
||||||
|
reader.onload = event => {
|
||||||
|
resolve(event.target.result)
|
||||||
|
}
|
||||||
|
reader.onerror = event => {
|
||||||
|
reject(event)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Calculates a Birthdate String in the Calendar of Bosparans Fall
|
||||||
|
* @param json json with the day, the month and the year of the birthday
|
||||||
|
* @returns {string} a string in the format of "DD.MMMM.YYYY BF"
|
||||||
|
*/
|
||||||
|
function calculateBirthdate(json) {
|
||||||
|
let day = json.gbtag
|
||||||
|
let month = months[parseInt(json.gbmonat) - 1]
|
||||||
|
let year = json.gbjahr
|
||||||
|
|
||||||
|
return `${day}. ${month} ${year} BF`
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parses a json into a fitting character-json
|
||||||
|
* @param rawJson the json parsed from the Helden-Software XML
|
||||||
|
* @returns {{}} a json representation of the character
|
||||||
|
*/
|
||||||
|
function mapRawJson(rawJson) {
|
||||||
|
let json = {}
|
||||||
|
let held = rawJson.helden.held;
|
||||||
|
json.name = held.name
|
||||||
|
json.meta = {}
|
||||||
|
json.meta.spezies = held.basis.rasse.string
|
||||||
|
json.meta.kultur = held.basis.kultur.string
|
||||||
|
let professions = []
|
||||||
|
for (let profession in held.basis.ausbildungen.ausbildung) {
|
||||||
|
profession = held.basis.ausbildungen.ausbildung[profession]
|
||||||
|
if (profession.tarnidentitaet) {
|
||||||
|
professions = [profession.tarnidentitaet]
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let professionString = profession.string
|
||||||
|
professions.push(professionString)
|
||||||
|
}
|
||||||
|
json.meta.professions = professions
|
||||||
|
json.meta.geschlecht = held.basis.geschlecht.name
|
||||||
|
json.meta.haarfarbe = held.basis.rasse.aussehen.haarfarbe
|
||||||
|
json.meta.groesse = held.basis.rasse.groesse.value
|
||||||
|
json.meta.augenfarbe = held.basis.rasse.aussehen.augenfarbe
|
||||||
|
json.meta.geburtstag = calculateBirthdate(held.basis.rasse.aussehen)
|
||||||
|
json.meta.alter = held.basis.rasse.aussehen.alter
|
||||||
|
json.meta.gewicht = held.basis.rasse.groesse.gewicht
|
||||||
|
json.meta.aussehen = [
|
||||||
|
held.basis.rasse.aussehen.aussehentext0,
|
||||||
|
held.basis.rasse.aussehen.aussehentext1,
|
||||||
|
held.basis.rasse.aussehen.aussehentext2,
|
||||||
|
held.basis.rasse.aussehen.aussehentext3,
|
||||||
|
]
|
||||||
|
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,
|
||||||
|
]
|
||||||
|
json.meta.titel = held.basis.rasse.aussehen.titel
|
||||||
|
json.meta.stand = held.basis.rasse.aussehen.stand
|
||||||
|
let attributes = held.eigenschaften.eigenschaft
|
||||||
|
json.attribute = {}
|
||||||
|
if (held.basis.gilde) {
|
||||||
|
json.attribute.gilde = held.basis.gilde.name
|
||||||
|
}
|
||||||
|
json.attribute.mu = getAttributeJson(attributes, "Mut")
|
||||||
|
json.attribute.kl = getAttributeJson(attributes, "Klugheit")
|
||||||
|
json.attribute.in = getAttributeJson(attributes, "Intuition")
|
||||||
|
json.attribute.ch = getAttributeJson(attributes, "Charisma")
|
||||||
|
json.attribute.ff = getAttributeJson(attributes, "Fingerfertigkeit")
|
||||||
|
json.attribute.ge = getAttributeJson(attributes, "Gewandtheit")
|
||||||
|
json.attribute.ko = getAttributeJson(attributes, "Konstitution")
|
||||||
|
json.attribute.kk = getAttributeJson(attributes, "Körperkraft")
|
||||||
|
json.attribute.mr = {
|
||||||
|
mod: filterAttribute(attributes,"Magieresistenz").mod
|
||||||
|
}
|
||||||
|
json.attribute.lep = {
|
||||||
|
mod: filterAttribute(attributes,"Lebensenergie").mod
|
||||||
|
}
|
||||||
|
json.attribute.aup = {
|
||||||
|
mod: filterAttribute(attributes,"Ausdauer").mod
|
||||||
|
}
|
||||||
|
json.attribute.asp = {
|
||||||
|
mod: filterAttribute(attributes,"Astralenergie").mod
|
||||||
|
}
|
||||||
|
json.attribute.kap = {
|
||||||
|
mod: filterAttribute(attributes,"Karmaenergie").mod
|
||||||
|
}
|
||||||
|
let attribute = filterAttribute(attributes,"Karmaenergie")
|
||||||
|
json.attribute.at = {
|
||||||
|
mod: attribute.mod,
|
||||||
|
aktuell: attribute.value
|
||||||
|
}
|
||||||
|
attribute = filterAttribute(attributes,"at")
|
||||||
|
json.attribute.pa = {
|
||||||
|
mod: attribute.mod,
|
||||||
|
aktuell: attribute.value
|
||||||
|
}
|
||||||
|
attribute = filterAttribute(attributes,"pa")
|
||||||
|
json.attribute.at = {
|
||||||
|
mod: attribute.mod,
|
||||||
|
aktuell: attribute.value
|
||||||
|
}
|
||||||
|
attribute = filterAttribute(attributes,"fk")
|
||||||
|
json.attribute.fk = {
|
||||||
|
mod: attribute.mod,
|
||||||
|
aktuell: attribute.value
|
||||||
|
}
|
||||||
|
attribute = filterAttribute(attributes,"ini")
|
||||||
|
json.attribute.ini = {
|
||||||
|
mod: attribute.mod,
|
||||||
|
aktuell: attribute.value
|
||||||
|
}
|
||||||
|
json.attribute.so = getAttributeJson(attributes, "Sozialstatus")
|
||||||
|
let benefits = []
|
||||||
|
for (let benefit in held.vt.vorteil) {
|
||||||
|
benefit = held.vt.vorteil[benefit]
|
||||||
|
let benefitJson = {
|
||||||
|
name: benefit.name,
|
||||||
|
}
|
||||||
|
if (benefit.value !== undefined) {
|
||||||
|
benefitJson.wert = benefit.value
|
||||||
|
}
|
||||||
|
benefits.push(benefitJson)
|
||||||
|
}
|
||||||
|
json.vornachteile = benefits
|
||||||
|
let specialAbilities = []
|
||||||
|
let liturgies = []
|
||||||
|
for (let specialAbility in held.sf.sonderfertigkeit) {
|
||||||
|
specialAbility = held.sf.sonderfertigkeit[specialAbility]
|
||||||
|
if (specialAbility.name.startsWith("Liturgie:")) {
|
||||||
|
liturgies.push({
|
||||||
|
name: specialAbility.name.replace("Liturgie:", "").trim(),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
let specialAbilityJson= {
|
||||||
|
name: specialAbility.name,
|
||||||
|
auswahlen: []
|
||||||
|
}
|
||||||
|
let fields = Object.keys(specialAbility)
|
||||||
|
if (fields.length > 1) {
|
||||||
|
for (let field in fields) {
|
||||||
|
field = fields[field]
|
||||||
|
if (field !== "name") {
|
||||||
|
let choices = specialAbility[field]
|
||||||
|
if (choices.hasOwnProperty("name")) {
|
||||||
|
specialAbilityJson.auswahlen.push(choices.name)
|
||||||
|
} else {
|
||||||
|
for (let choice in choices.wahl) {
|
||||||
|
choice = choices.wahl[choice]
|
||||||
|
specialAbilityJson.auswahlen.push(choice.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
specialAbilities.push(specialAbilityJson)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
json.sonderfertigkeiten = specialAbilities
|
||||||
|
json.liturgien = liturgies
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
json.talente = talents
|
||||||
|
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
|
||||||
|
let combatValues = []
|
||||||
|
for (let combatValue in held.kampf.kampfwerte) {
|
||||||
|
combatValue = held.kampf.kampfwerte[combatValue]
|
||||||
|
combatValues.push({
|
||||||
|
name: combatValue.name,
|
||||||
|
at: combatValue.attacke.value,
|
||||||
|
pa: combatValue.parade.value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
json.kampfwerte = combatValues
|
||||||
|
let notes = []
|
||||||
|
for (let note in held.kommentare) {
|
||||||
|
note = held.kommentare[note]
|
||||||
|
if (note.hasOwnProperty("key")) {
|
||||||
|
notes.push({
|
||||||
|
key: note.key,
|
||||||
|
notiz: note.kommentar,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
json.notizen = notes
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: held.name,
|
||||||
|
system: json,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param attributes an array with the attributes
|
||||||
|
* @param name the name of the chosen attribute
|
||||||
|
* @returns {{}} a representation of the chosen Attribute
|
||||||
|
*/
|
||||||
|
function getAttributeJson(attributes, name) {
|
||||||
|
let attribute = filterAttribute(attributes, name)
|
||||||
|
return {
|
||||||
|
start: parseInt(attribute.startwert),
|
||||||
|
aktuell: parseInt(attribute.value),
|
||||||
|
mod: parseInt(attribute.mod),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* filters a given attribute array based on the name of an attribute
|
||||||
|
* @param attributes the attribute array
|
||||||
|
* @param name the name of the desired attribute
|
||||||
|
* @returns {{}} the json of the desired attribute
|
||||||
|
*/
|
||||||
|
function filterAttribute(attributes, name) {
|
||||||
|
return attributes.filter(attribute => attribute.name === name)[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
Hooks.on("getActorContextOptions", (application, menuItems) => {
|
||||||
|
menuItems.push({
|
||||||
|
name: "Import from XML",
|
||||||
|
icon: '<i class="fas fa-file"></i>',
|
||||||
|
callback: (li) => {
|
||||||
|
const actorId = li.getAttribute("data-entry-id")
|
||||||
|
const actor = game.actors.get(actorId)
|
||||||
|
actor.import()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
<form class="flexcol" autocomplete="off">
|
||||||
|
<header class="sheet-header">
|
||||||
|
<div class="header-fields">
|
||||||
|
<h1 class="charname">{{actor.name}}</h1>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<section class="sheet-body">
|
||||||
|
<textarea readonly>{{formatCharacter actor}}</textarea>
|
||||||
|
</section>
|
||||||
|
</form>
|
||||||
Loading…
Reference in New Issue