Compare commits

...

141 Commits

Author SHA1 Message Date
Byroks 4a9afcf150 v2.7.2 2024-09-21 10:21:19 +02:00
Byroks 6a90581c4e Fix Versteckte Würfe & Ungelernte Würfe auf EW 2024-09-21 10:17:53 +02:00
LeFrique 7c7ba3679b KUS-Update (#116)
+ Fine Arts from KUS-QB
+ Bugfix for Wealth (again parseFloat) on higher and mixed values for gold, silver and copper

Neuer/alter Mitspieler mit viel zuviel Vermögen deckt kleine Mängel auf, immer diese reichen Elfen... und ich hab schnell noch die neuen Fertigkeiten für die Küstenstaaten eingetragen.

Reviewed-on: #116
Reviewed-by: Byroks <byroks@gmail.com>
Co-authored-by: LeFrique <lefrique@live.de>
Co-committed-by: LeFrique <lefrique@live.de>
2024-06-02 20:17:20 +02:00
Byroks 28e960dbf1 V2.7.1 2024-05-27 11:59:28 +02:00
Byroks e1c27bb3f1 Remove Console.log 2024-05-27 11:57:05 +02:00
Byroks f06fbb2687 Hot Fix
Changes:
 + NPC Stat anzeige updaten damit boni mit angezeigt werden
 + Shit fix Mods da attribute Mods Sekundäre effekte (Schadensbonus zb.) nicht angepasst haben
2024-05-27 11:56:10 +02:00
Byroks c5ce058f44 V2.7.0 2024-05-27 10:12:23 +02:00
Byroks 32bf1ba747 Fix PP anzeige von Zaubern (#115)
Changes:
 + PP werden wieder angezeigt
 + Es werden nur PP Angezeigt von Zauberschulen wo die lernkosten ungleich 0 sind
Reviewed-on: #115
2024-05-27 10:04:26 +02:00
Byroks 38f1c90c09 Fix Bonus bei Wurf anzeige (#114)
Changes:
 + Situations Boni wird nicht mehr auf den Würfel gerechnet sondern seperat angezeigt wie andere Boni
Reviewed-on: #114
Reviewed-by: Le-Frique <lefrique@live.de>
2024-05-27 10:03:54 +02:00
Byroks 1852f2bf08 Sneak Fixes
Changes:
 + EP Input vergrößert
 + Verstecke Ungelernte Fähigkeiten auf Spieler Bogen wie bei NPC Bogen
 + Fix Mods (again)
 + nutze richtige movement wert bei NPC Bogen
2024-05-26 09:56:02 +02:00
Byroks 918b32fda0 Attribute Mods verändern Boni nicht (#111)
Problem:
 + Mods für die Attribute (wie zb. bei dem Zauber Stärke) haben davon abgeleitete Werte (Wie Schadensbonus) nicht verändert

Changes:
 + Mods werden vor den abgeleiteten Werten ausgewertet

Reviewed-on: #111
Reviewed-by: Le-Frique <lefrique@live.de>
2024-05-22 08:15:47 +02:00
oskaloq 3ecd2c6c1e Vereinfachter-NPC/Kreaturen-Bogen (#107)
Ich habe mal den ersten Entwurf eines NPC Bogens fertiggestellt. Ist jetzt ein eigener Actor Type geworden und nicht nur ein alternativer Char Bogen:
Einfach beim Erstellen eines neuen Actors NPC wählen.

Co-authored-by: Ender <harald@drueppels.de>
Co-authored-by: LeFrique <lefrique@live.de>
Co-authored-by: Byroks <byroks@gmail.com>
Reviewed-on: #107
Reviewed-by: Le-Frique <lefrique@live.de>
2024-05-14 11:38:20 +02:00
LeFrique 37d6ba12e7 tragkraft-containerwert-abw-kidoprep (#103)
+ Added ABW to items
+ Added warning for over-capacity
+ Added Valuecalculation for containers
+ Updated KiDo-template

Reviewed-on: #103
Reviewed-by: Byroks <byroks@gmail.com>
Co-authored-by: LeFrique <lefrique@live.de>
Co-committed-by: LeFrique <lefrique@live.de>
2024-05-01 19:10:47 +02:00
Byroks 5a1e11d0d7 Sneak update, AP Cost not working correctly 2024-04-27 18:45:20 +02:00
oskaloq c5e5ba199b changed manifest for easier update (#97)
Co-authored-by: Ender <harald@drueppels.de>
Reviewed-on: #97
Reviewed-by: Byroks <byroks@gmail.com>
2024-04-01 19:30:19 +02:00
oskaloq 08e767afcb Drag and Drop für Container #98 (#99)
Items können jetzt per Drag and Drop in Container verschoben werden. Werden sie nicht in einen Container gedroppt, landen sie wieder in der allgemeinen Item Übersicht.

Co-authored-by: Ender <harald@drueppels.de>
Reviewed-on: #99
Reviewed-by: Byroks <byroks@gmail.com>
2024-03-31 18:51:01 +02:00
Byroks fb30f8fe40 v2.6.0 2024-03-29 14:32:33 +01:00
Byroks 2a1262662f Situationsbedingte-Boni/Mali-#41 (#95)
Changes:
 + Popup für Situationsbedinge Boni/Mali, Schwellenwert und RollMode (Sichtbarkeit)
 + neuwürfel/verändern des wurfes durch glückspunkte und schicksalsgunst
Co-authored-by: Ender <harald@drueppels.de>
Reviewed-on: #95
2024-03-29 14:28:49 +01:00
Byroks a4cf10c5f1 #64-anzeige-von-zauber-pp (#96)
Reviewed-on: #96
2024-03-29 14:02:47 +01:00
LeFrique 7ac704cc61 Entbehrungen (#89)
Ich habe die Entbehrungswerte für Zähigkeit unter den Grundwerten abgelegt und werde die Tage noch Entbehrungseffekte und ein Macro in der Extension dafür anlegen. Die Boni für die Klassen wie zB Barbar +10 könnten wir dann da direkt mit in der jeweilige Klasse berücksichtigen. Grundsätzlich kann man das aber jetzt schonmal nutzen und der Grundwertebogen war mir zu leer ;) ![grafik](/attachments/fbb80a27-91d7-4b00-bd39-7c24af3bda60)

Co-authored-by: Byroks <byroks@gmail.com>
Reviewed-on: #89
Co-authored-by: LeFrique <lefrique@live.de>
Co-committed-by: LeFrique <lefrique@live.de>
2024-03-24 20:02:24 +01:00
Byroks 046d5f0286 #91 Automatische Praxispunkte (#93)
Changes:
 + implementation von Automatischen Praxispunkten
 + Hinzufügen von System Settings zur abschaltung von Automatischen Praxispunkten
 + Aufräumen von Helpers und settings in eigene Dateien
Co-authored-by: LeFrique <lefrique@live.de>
Reviewed-on: #93
2024-03-24 15:09:08 +01:00
Byroks 3a58485d27 #90 Clean Spell Button funktioniert nicht (#94)
Changes:
 + hinzufügen von roll funktion für Zauberwert
Reviewed-on: #94
Reviewed-by: Le-Frique <lefrique@live.de>
2024-03-24 15:06:30 +01:00
Byroks 12e6412a9f #70-classes-as-items (#92)
Co-authored-by: LeFrique <lefrique@live.de>
Reviewed-on: #92
2024-03-23 19:17:54 +01:00
LeFrique af6fdbbf89 Skill & Sheets Update (#88)
+ Added FW-Increase/Decrease on Weapon and Language Skills
+ Added ItemIcons for Skills, Gear, Spells, Combat and Effects
+ Re-Added Belastungseffect with all mods working nearly smoothless (only bugging on new actors once created; could be commented out if not approvable until better solution exists)

![grafik](/attachments/451f5642-8250-4331-bdb7-04019ce2525c)

Reviewed-on: #88
Reviewed-by: Byroks <byroks@gmail.com>
Co-authored-by: LeFrique <lefrique@live.de>
Co-committed-by: LeFrique <lefrique@live.de>
2024-03-14 20:58:52 +01:00
LeFrique 43375a19c8 Kampfkunstupdate (#86)
+ Added more types & variants
+ Modified Kampfkunstitem, Combatsheet and rollmessage

Hab grad die Kampfkünste in der extension anscheinend direkt nach develop durchgepusht ohne meine kampfkunstbranch dazwischen, hier dann auch die Anpassungen im System dafür. Läuft beides bei mir rund.

Reviewed-on: #86
Reviewed-by: oskaloq <os_ka_loq@gmx.de>
Co-authored-by: LeFrique <lefrique@live.de>
Co-committed-by: LeFrique <lefrique@live.de>
2024-03-14 11:35:26 +01:00
oskaloq a03af18281 Zaubertab ergänzen #79 + Kampftab ergänzen #78 (#87)
- Zaubertab um Header (Zaubern + Resistenzen) ergänzt (Footer steht noch aus; am besten zusammen mit der PP Überarbeitung)
- Werte in der Zauber Tabelle ergänzt
- Zauber "ausrüstbar" gemacht, so dass sie im Kampftab angezeigt werden
- Kampftab um Initiative (Anführen) ergänzt

Co-authored-by: Ender <harald@drueppels.de>
Reviewed-on: #87
Reviewed-by: Byroks <byroks@gmail.com>
2024-03-13 22:22:54 +01:00
Byroks 08ca1cedce Merge branch 'develop' of https://git.byroks.de/MidgardVTT-Entwicklung/foundry-vtt-system-midgard5 into develop 2024-03-04 14:17:39 +01:00
Byroks a9895d612a v2.5.0 2024-03-04 14:16:22 +01:00
Byroks 15473fb0db Remove Lasteneffekte (#84)
Changes:
 + Aktive Effekte wurden entfernt
 + Überschrittene Lasten werden Rot eingefärbt
Reviewed-on: #84
2024-03-04 14:14:19 +01:00
Byroks b83c57b5c8 Fix increase/decrease EW button 2024-03-04 10:34:51 +01:00
Byroks e465bac5ef Sortierbare Items (#68)
Changes:
 + Items sind jetzt sortierbar
 + Items können jetzt auf andere Actor übertragen werden
 + Löschen button für Mods
Reviewed-on: #68
2024-03-04 10:01:47 +01:00
LeFrique bb9d20f586 Fertigkeitenboni (#77)
+ Added bonus on Aussehen depending on fw: athletik gem. KOD S. 104
+ Added bonus on Bewegungsweite depending on fw: laufen gem. KOD S. 116
+ Added Skill increase/decrease buttons like on quantity

Reviewed-on: #77
Reviewed-by: oskaloq <os_ka_loq@gmx.de>
Co-authored-by: LeFrique <lefrique@live.de>
Co-committed-by: LeFrique <lefrique@live.de>
2024-03-03 18:43:43 +01:00
oskaloq 9ff50fbd7d #75 Build lässt sich wegen fehlendem packs Ordner nicht mehr durchführen (#76)
Keine Ahnung, warum der packs Ordner beim letzten Pull Request gelöscht wurde. Hatte den Build vor dem Request noch einmal getestet. Ich habe jetzt vorsichtshalber eine empty.md Datei im Ordner erstellt.

Ich habe auch nochmal verifiziert, ob die Kompendium Folders in einer neuen Welt auch wirklich nicht angelegt werden:
![image](/attachments/828ccf31-c039-4534-a57a-4f06ae983da7)

Co-authored-by: Ender <harald@drueppels.de>
Reviewed-on: #76
Reviewed-by: Byroks <byroks@gmail.com>
Co-authored-by: oskaloq <os_ka_loq@gmx.de>
Co-committed-by: oskaloq <os_ka_loq@gmx.de>
2024-02-27 13:08:31 +01:00
oskaloq 1801599e8d Layout Wiederherstellung im Ausrüstungstab #73, Kompendium Packs aus dem System entfernen #71, "Sonstige Werte" doppelt im Kampftab vorhanden #69 (#74)
Erledigung folgender Issues:
- Layout Wiederherstellung im Ausrüstungstab #73
- Kompendium Packs aus dem System entfernen #71
- "Sonstige Werte" doppelt im Kampftab vorhanden #69
- Wiederherstellung einiger Features im Character Sheet, die durch das Lasten Update verloren gegangen sind
- Anpassung des Editors im Descript Tab: Entfernung des deprecated Parameter content

Co-authored-by: Ender <harald@drueppels.de>
Reviewed-on: #74
Co-authored-by: oskaloq <os_ka_loq@gmx.de>
Co-committed-by: oskaloq <os_ka_loq@gmx.de>
2024-02-27 10:17:45 +01:00
Byroks a0037aa1bf Hotfix - reapply missing css class 2024-02-25 10:04:12 +01:00
Byroks 8ce84bad19 #55 Default FW/EW für waffen auf 4 setzen (#63)
Changes:
 + falls eine Waffe keinen Skill ausgewählt hat, ist der standard wert 4 anstelle von 0
Reviewed-on: #63
Reviewed-by: Le-Frique <lefrique@live.de>
2024-02-24 13:58:02 +01:00
Byroks 5b1b0deb7a #6 Lasten und Gewichte (#52)
Co-authored-by: LeFrique <lefrique@live.de>
Reviewed-on: #52
2024-02-24 11:23:37 +01:00
Byroks 06ef797ef2 #57 Damage auf tokens (#58)
Changes:
 + Fix um Heilung anzurechnen
 + Finde token über Canvas Selected
 + möglich schaden auf mehrere token zeitlgiehc anzurechnen.
Reviewed-on: #58
2024-02-21 22:30:08 +01:00
Byroks 1624602407 + Button für Skills (#59)
Changes:
 + Styling anpassung für + buttons
 + CreatItem funktion angepasst, man kann optionen reingeben
 + button um skills zu erstellen eingefügt
Reviewed-on: #59
2024-02-21 22:29:58 +01:00
Byroks a46ef87e3f Button um Kampf beizutreten (#61)
Changes:
 + Button um Kampf beizutreten
 + buttons um initiative zu verändern für Fernangriffe und Zauber
Reviewed-on: #61
2024-02-21 22:29:48 +01:00
Byroks c2aa466ce1 v2.4.2 2024-02-05 13:30:20 +01:00
Byroks 24426bb248 HotFix nicht öffenbare Charaktere
Changes:
 + Currency hat bei (fast) allen Items gefehlt weswegen das Charakterblatt nicht mehr öffenbar war, nachdem man Wert und Currency eingetragen hat.
 + Beachte Menge für Vermögensrechnung
 + Hort rechnung beachtet jetzt Currency
2024-02-05 13:29:29 +01:00
Byroks 26b2bddc2d v2.4.1 2024-02-05 10:28:46 +01:00
oskaloq 9f1334da4f - Container behavior for Weapons, Def. Weapons and Armor is now the same as for items (#53)
- Fixed some Bugs

Co-authored-by: Ender <harald@drueppels.de>
Co-authored-by: Byroks <byroks@gmail.com>
Reviewed-on: #53
Reviewed-by: Byroks <byroks@gmail.com>
Co-authored-by: oskaloq <os_ka_loq@gmx.de>
Co-committed-by: oskaloq <os_ka_loq@gmx.de>
2024-01-31 18:31:32 +01:00
Byroks 454982906f Hotfix - can't open charaktersheet
Problem:
 +sometimes items had a null formula which blocked opening the sheet

Changes:
 + add ? to catch nulls
2024-01-22 22:24:12 +01:00
Byroks 33c65735bd v2.4.0 2024-01-20 15:31:35 +01:00
Byroks 2bfd3a7d6a #46-problems-with-character-description-editor (#50)
Changes:
 + adjust height and width of the editor

WIP for #46
Closes #44

Reviewed-on: #50
2024-01-20 13:58:22 +01:00
Byroks 03b87f2df0 update url 2024-01-20 13:44:06 +01:00
Byroks 9d72b31d5f Add Items on Character Sheet
Changes:
 + add button to add all different kind of items directly onto the character sheet
 + fix #1 by correctly updating the item
2024-01-20 12:37:05 +01:00
oskaloq c13fef5103 Zusammenführung-von-Fertigkeiten,-Waffen-und-Rüstungen-im-Kampf-Tab-#15 (#48)
- Created character description tab
- Redesigned skill, gear and combat tab
- Weapons, defense weapons and armor is still in the gear tab. If you equip them (now directly possible via click on the equip icon), they appear in the combat tab. Reason: This holds the combat tab clean for combat stuff.

Co-authored-by: Ender <harald@drueppels.de>
Reviewed-on: #48
Reviewed-by: Byroks <byroks@gmail.com>
2024-01-16 11:25:39 +01:00
Byroks abf8077131 #33 Wrong wealth calculation (#34)
Changes:
 + add function to adjust item value depending on currency
Co-authored-by: Simon Gustavs <simon.gustavs@bms-cs.de>
Reviewed-on: #34
Reviewed-by: oskaloq <os_ka_loq@gmx.de>
2024-01-16 08:29:14 +01:00
Byroks b5b75aa2c6 #18 Remove ContainerId from containers (#29)
Changes
 + remove containerId variable from containers as it's not needed

Reviewed-on: #29
Reviewed-by: oskaloq <os_ka_loq@gmx.de>
2024-01-15 14:15:30 +01:00
Byroks 7368673ba3 Update .gitea/workflows/add-issue-to-project.yaml 2024-01-08 20:42:22 +01:00
Byroks a606750b23 Update .gitea/workflows/add-issue-to-project.yaml 2024-01-08 20:41:15 +01:00
Byroks 7358b67da2 Update .gitea/workflows/add-issue-to-project.yaml 2024-01-08 20:41:05 +01:00
Byroks 2a36b8eaa1 Update .gitea/workflows/add-issue-to-project.yaml 2024-01-08 20:38:50 +01:00
Byroks f38ef8aa6d Update .gitea/workflows/add-issue-to-project.yaml 2024-01-08 16:16:04 +01:00
Byroks 2ac8a6bba4 Update .gitea/workflows/add-issue-to-project.yaml 2024-01-08 16:09:13 +01:00
Byroks 41fb1a8879 Update .gitea/workflows/add-issue-to-project.yaml 2024-01-08 16:02:37 +01:00
Byroks ff74871a0c Update .gitea/workflows/add-issue-to-project.yaml 2024-01-08 12:56:49 +01:00
Byroks f8b65c030f Update .gitea/workflows/add-issue-to-project.yaml 2024-01-08 12:39:39 +01:00
Byroks 31a4ccfda1 Update .gitea/workflows/add-issue-to-project.yaml 2024-01-08 12:37:43 +01:00
Byroks c24e2b7af2 Update .gitea/workflows/add-issue-to-project.yaml 2024-01-08 12:28:41 +01:00
oskaloq cfdba0ee75 Anpassung-des-Character-Sheet-Headers-#13 (#28)
- Made character sheet header more responsive
- Changed Logo
- Changed "all gear items" container, that it shows items not in dedicated containers ( unless "Alle" checkbox is set)

Co-authored-by: Ender <harald@drueppels.de>
Co-authored-by: Byroks <byroks@gmail.com>
Reviewed-on: #28
Reviewed-by: Byroks <byroks@gmail.com>
2024-01-07 22:53:16 +01:00
Byroks d67de1b064 Update .gitea/workflows/add-issue-to-project.yaml 2024-01-07 16:47:12 +01:00
Byroks 718f1eab99 Update .gitea/workflows/add-issue-to-project.yaml 2024-01-07 16:38:35 +01:00
Byroks 47fd5b7763 Update .gitea/workflows/add-issue-to-project.yaml 2024-01-07 16:37:27 +01:00
Byroks ad884994dd Update .gitea/workflows/add-issue-to-project.yaml 2024-01-07 16:17:20 +01:00
Byroks b08bd195c7 Update .gitea/workflows/add-issue-to-project.yaml 2024-01-07 15:45:46 +01:00
Byroks c83cd8f079 Update .gitea/workflows/add-issue-to-project.yaml 2024-01-07 15:40:56 +01:00
Byroks b1ef88235f Update .gitea/workflows/add-issue-to-project.yaml 2024-01-07 15:37:37 +01:00
Byroks da1ae4e16e Update .gitea/workflows/add-issue-to-project.yaml 2024-01-07 15:35:54 +01:00
Byroks 840a7c1dc4 Update .gitea/workflows/add-issue-to-project.yaml 2024-01-07 15:33:26 +01:00
Byroks 4825166f87 Add .gitea/workflows/add-issue-to-project.yaml 2024-01-07 15:06:01 +01:00
LeFrique b8e873537c Zwergenhort (#4)
Mein Geschenk zu Weihnachten:

Implementierung des Zwergenhort gem. KOD S. 167 mit Angabe aktueller Mindesthort für aktuellen Grad und benötigtem Hort für nächsten Grad bei Zwergen. Der Hort erscheint nur bei ausgewählter Rasse Zwerg und wird bei allen anderen Rassen versteckt. Die Anrechnung von Gold oder Gegenständen wie auch im KOD erwähnt erfordert die Implementierung eines Goldmanagements und am besten auch eine Neustrukturierung des Charakterbogens (s. weitere Issues).

Frohe Weihnachten ;)

Co-authored-by: Byroks <byroks@gmail.com>
Reviewed-on: #4
Co-authored-by: LeFrique <lefrique@live.de>
Co-committed-by: LeFrique <lefrique@live.de>
2024-01-07 14:31:20 +01:00
Byroks 975bcd1e15 #10 Kampfkunst nicht öffenbar (#11)
Änderungen:
 + auskommentierte if Bedingung wieder drin
 + if Bedingung angepasst

Reviewed-on: #11
Reviewed-by: Le-Frique <lefrique@live.de>
2024-01-07 14:29:39 +01:00
oskaloq b945f22710 Charakterbogen anpassen #7 (#9)
- Use of flexboxes in two columns for better display
- Introduction of item containers for the different storage of items

Co-authored-by: Ender <harald@drueppels.de>
Co-authored-by: Byroks <byroks@gmail.com>
Reviewed-on: Byroks/foundry-vtt-system-midgard5#9
Reviewed-by: Byroks <byroks@gmail.com>
2024-01-03 15:57:15 +01:00
Byroks 6baf9a0269 Change git Path (#3)
Changes:
 + change github urls to git.byroks
Reviewed-on: Byroks/foundry-vtt-system-midgard5#3
Reviewed-by: Le-Frique <lefrique@live.de>
2023-12-18 19:53:37 +01:00
Byroks 91f12b11da v2.3.1 2023-12-15 21:36:33 +01:00
Byroks bfa51605bc
Add Consumable Items (#62)
Changes:
 + add Quantity value for items
 + add plus and minus buttons for list
 + add roll button if item contains formulas
 + decrease quantity by 1 if rolled
2023-12-15 21:34:32 +01:00
Byroks c313d3448c
Add Roll Modification (#61)
Changes:
 + add roll Mod (only for attributes)
 + check for roll mods when rolling on attributes
2023-12-15 20:40:23 +01:00
Byroks 31cfd52131
Add currency to character sheet (#60)
Changes:
 + add fields to track currency
 + show value of standard items
2023-12-15 20:39:29 +01:00
Byroks a5336faa94 v2.3.0 2023-12-13 18:52:41 +01:00
Byroks a56e6bab3d
Automatically select skill for effects (#59)
Changes:
 + when a mod gets added, check if it's a skill
 + if it's a skill, find appropiate ID in actors item list and apply it to the mod
2023-12-13 18:46:49 +01:00
LeFrique fed1175987
26 perception drinking all abilities (#56)
* Innate abilities

+ Added Perception as fixed innate ability
+ Added Drinking as fixed innate ability
+ Set Luckpoints to 0

* Duration Update

+ Added Duration to Effects
+ Added Perception to Eye & Ear Injury

* Fixed like recommended

+ Fixed M5Base
+Fixed M5Character
+ Fixed M5Rolls
+ Fixed Skills HBS
+ Fixed BrawlFw
+ Fixed Effect (not saved already)

* fix minor issues

---------

Co-authored-by: Byroks <byroks@gmail.com>
2023-12-13 18:45:35 +01:00
Byroks 1e27e135cf
15 add duration to active effects (#50)
* Add Effect Duration & Rework Combat tracker

Changes:
 + rework combat tracker to display every uneven round as Movementphase
 + rework combat tracker to display every even round as actionphase
 + add possibility for effects durations
 + effects duration decreases with every actionphase
 + add enum for time Units
 + update localization
 + add display of remaining time on effects
 + add duration for spelleffect "Bärenwut"

* add LP AP Manipulation through effects

Changes:
 + add LimitHeal function
 + adjust LP AP Values if Mod exists in an effect

* Fix linked actor not being updated
2023-12-11 17:36:12 +01:00
LeFrique 30e94741bf
Update main.hbs (#55)
+ Switched Ko and Gw to match dice description above dice symbols in header.
2023-12-09 18:24:09 +01:00
LeFrique 2dccbf3de3
Fix packfolders (#47)
+ Added missing curly brace
+ Added Injuries in packFolders
2023-12-06 18:43:23 +01:00
LeFrique 9814c44045
Added Injuries & in Macros, Fixes (#25)
Added:
+ Injuries as Effects
+ Added Injury Effects to Macro Schwere Verletzungen
Fixed:
+ Pagedescription in Spell Effects
+ Images (again) in Combat Conditions
2023-12-06 16:30:13 +01:00
Byroks 53ff2ece7d v2.2.0 2023-12-06 16:08:39 +01:00
Byroks 04a30a70b9 Minor Style Changes 2023-12-06 16:08:08 +01:00
Byroks b5cffae778
Fix Armor misscalculation (#46)
Changes:
 + mod operation "add" can't go into negative numbers
2023-12-06 14:49:12 +01:00
Byroks db23081a9a
Fix Movement Boni being applied multiple times (#45)
Changes:
 + seperate display of Base Movement speed and calculated movement speed
 + for asthetic reasons move GiT to Berechnete Werte
2023-12-06 12:31:34 +01:00
LeFrique e753f6392d
Delete Maps (#43)
- Deleted Assets
- Deleted Packs
+ Removed Scenepacks from system.json
2023-12-06 11:17:05 +01:00
Byroks 2b4e6b18d0
28 apply damage through chat (#40)
* Add Rightclick menu to apply damage/heal

Changes:
 + add rightclick context menu for rolls
 + only appears if keyword Schaden exists
 + calculate damage from all rolls with keyword Schaden
 + possible to apply damage or heal actor or if present token

ToDo:
 + add button that does the same

* Add Rüstungsschutz to damage calculation

Changes:
 + Add Damage application from chat
 + take token first, if none exist, take actor
 + include damage reduction from equipped armor
 + damage appliaction is only accesible through right click on roll

* Fix falsy display of rightclick context menu
2023-12-06 11:14:35 +01:00
oskaloq 0fe61e5bbb
Comprehensive overhaul of the character sheet design. (#35) 2023-12-04 11:44:32 +01:00
LeFrique 46cac30dcd
17 add rüstungskammer + 21 Restructure Compendium (#31)
* Rüstkammer, Fixes & Preparation

+ Added Rüstkammer
+ Added Pagedescriptions in Ausrüstung
+ Prepared Compendium Folders

* Compendium Folders & Fixes

+ Added Effects to magical Gear
+ Added more Combat Conditions for Gear Effects
+ Added Markup to some Items for better visualization in Items or chat, more to follow
+ Solved Combat Folders (works only in new World!)

---------

Co-authored-by: Byroks <byroks@gmail.com>
2023-12-03 15:29:12 +01:00
Byroks 7e6147299b
Adjust Mod Calculation (#30)
Changes:
 + Adjust mod calculation
 + remov max 0 from subtract and addition
 + check in skills for subtract mod
2023-12-03 13:07:41 +01:00
Byroks f9737a4cb9
Aktualisieren von LICENSE 2023-12-01 22:10:24 +01:00
LeFrique 6ff4f16f9d
18 add more operations for modifiers (#23)
* Added Operations and Combat Conditions

+ Added Multiply, Division and Subtract operations for modifiers
+ Added Combat Conditions Effects form Ars Armorum

* Added Math.floor()

* Fixed Operations and Combat Conditions
2023-12-01 19:04:58 +01:00
LeFrique 725dd8c504
Added Operations and Combat Conditions (#22)
* Added Operations and Combat Conditions

+ Added Multiply, Division and Subtract operations for modifiers
+ Added Combat Conditions Effects form Ars Armorum

* Added Math.floor()
2023-12-01 15:26:49 +01:00
Byroks 48883c3102
Add Description to bottom of rolls (#19)
Changes:
 + Add helper to strip Html
 + add description of items to bottom of roll
2023-11-30 18:13:04 +01:00
Byroks 250fc499ae v2.1.0 2023-11-30 16:17:04 +01:00
Byroks 28595e7dd0
Make Items with mods equippable (#11)
Changes:
 + Items that can influence you stats are equippable
 + only equipped items influence your stats
 + Armor now influences your stats
 + move mods into a partial for easier changes
2023-11-30 15:50:59 +01:00
Byroks 8095785fc2
Movement stat (#10)
Changes:
 + make movement stat work and be moddable by effects
2023-11-29 10:14:49 +01:00
Byroks e141839055
Merge branch 'main' into develop 2023-11-28 19:50:38 +01:00
Byroks 14e005cb0a v2.0.0 2023-11-28 19:48:14 +01:00
Byroks c635c54f24
Dev Kampfkünste Items & Integration (#7)
Changes:
 + add kampfkuenste template
 + add kampfkuenste tab
 + make kampfkuenste rollable
 + update localization
2023-11-28 19:42:38 +01:00
Byroks e27f4209e5 Squashed commit of the following:
commit 0bfa224dae
Author: Byroks <byroks@gmail.com>
Date:   Mon Nov 27 19:56:05 2023 +0100

    V1.3.1 (#6)

    * v1.3.1

    * v1.3.1

    * update .gitingore

commit 35a6b0fae9
Author: Byroks <byroks@gmail.com>
Date:   Mon Nov 27 19:48:56 2023 +0100

    v1.3.1

commit db21ca93b0
Author: Byroks <byroks@gmail.com>
Date:   Sun Nov 26 13:13:13 2023 +0100

    subtract ap when casting spell

    Changes:
     + subtract AP when casting a spell
2023-11-27 20:05:20 +01:00
Byroks 0bfa224dae V1.3.1 (#6)
* v1.3.1

* v1.3.1

* update .gitingore
2023-11-27 20:04:06 +01:00
Byroks 35a6b0fae9 v1.3.1 2023-11-27 19:48:56 +01:00
Byroks db21ca93b0 subtract ap when casting spell
Changes:
 + subtract AP when casting a spell
2023-11-26 13:13:13 +01:00
Byroks 7bf0fd90b0 update verified and maximum version 2023-11-25 19:33:03 +01:00
Byroks a7bdd0434e Delete midgard5-v1.3.0.zip 2023-11-25 16:38:39 +01:00
Byroks 97d4a35cd6 update localize Keys
Changes:
 + update localize Keys, to conform with v11
2023-11-25 16:38:05 +01:00
Byroks c2996aa974 Fix Raufen roll
Changes:
 + fix roll attributes for Raufen
2023-11-25 16:04:17 +01:00
Byroks bf4f49755a adjust iniative roll
Changes:
 + fix iniative stat
2023-11-25 15:54:53 +01:00
Byroks 57bffd492a
Update de.md 2023-11-25 14:20:47 +01:00
Byroks 5a36ee9eab
V1.3.0 (#3)
* v1.3.0

* v1.3.0
2023-11-24 21:01:10 +01:00
Byroks a8a1e6e133 fix gulpfile 2023-11-24 20:54:22 +01:00
Byroks 3bf2612dd0 update system.json & gitignore 2023-11-24 20:47:21 +01:00
Byroks 68cb8fcf6d Include Weapons and effects
Changes:
 + include weapon pack and effect pack
 + handle effects as own entity
 + effects can influence your attributes and skills
 + add Aktive Effekte page for effects on your character
2023-11-24 20:11:36 +01:00
Byroks 4b2daef20a fix Gifttolleranz naming, parsing and display 2023-11-22 23:13:19 +01:00
Byroks 792c578e0f
Merge pull request #1 from LeFrique/main
Added skills & weapons from all Sourcebooks,GiT&B
2023-11-22 22:19:54 +01:00
Byroks 3b051760ae
Merge branch 'main' into main 2023-11-22 22:19:20 +01:00
Byroks bffbe97805 Revert "update system id"
This reverts commit 6428b3252e.
2023-11-22 19:11:53 +01:00
Byroks e21e5a91be Revert "adjust to id change"
This reverts commit 30d0924e3d.
2023-11-22 19:11:44 +01:00
Byroks 783f7f020b Revert "update version"
This reverts commit c77818199a.
2023-11-22 19:11:36 +01:00
Byroks ad841b111f Revert "remove"
This reverts commit 5277a3ca4b.
2023-11-22 19:11:17 +01:00
LeFrique ba2992221d Added skills & weapons from all Sourcebooks,GiT&B 2023-11-21 20:03:46 +01:00
Byroks 5277a3ca4b remove 2023-11-21 19:57:45 +01:00
Byroks c77818199a update version 2023-11-21 19:53:32 +01:00
Byroks 30d0924e3d adjust to id change 2023-11-21 19:50:39 +01:00
Byroks 6428b3252e update system id 2023-11-21 19:18:05 +01:00
Byroks e85fd1c41f fix Zaubern EW display in spell
Changes:
 + fix Zaubern EW display in spell list
2023-11-19 21:13:29 +01:00
Byroks d9e7152b4d verson change v1.2.2 2023-11-19 20:58:03 +01:00
Byroks 9e7d81f413 version change to v1.2.2 2023-11-19 20:57:16 +01:00
Byroks 8dd29e8da5 hide skill when learned
Changes:
 + Hide learned skills from unlearned skill list
2023-11-19 20:52:29 +01:00
Byroks 0d259f40a7 adjust version to 1.2.1 2023-11-17 16:10:31 +01:00
Byroks 4ec3cc9570 add race boni and default resistance rolls
Changes:
 + add Race Selection Dropdown
 + change resistance/defense value calculation, based on race, stats and class
 + add default rolls for defense and resistances
2023-11-17 16:09:24 +01:00
Byroks 2b02f787f2 fix spelling mistake in macros 2023-11-17 09:27:33 +01:00
91 changed files with 6256 additions and 3959 deletions

View File

@ -0,0 +1,15 @@
name: Move new issues into To Do
on:
issues:
types: [opened]
jobs:
createCard:
runs-on: ubuntu-latest
steps:
- name: Close Issue
run: >
curl -X PATCH -H "Content-Type: application/xml"
-H "Authorization: token ${{ secrets.GITEA_TOKEN }}
-d '{ "state": "To Do" }'
"${{ gitea.event.issue.url }}"

1
.gitignore vendored
View File

@ -5,3 +5,4 @@ package-lock.json
source/packs/
source/generators/
dist
*.zip

View File

@ -1,6 +1,7 @@
MIT License
Copyright (c) 2022
Copyright (c) 2022 Michael Stein
Copyright (c) 2023 Byroks
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="512" height="512"><path fill="#fff" d="M262.406 17.188c-27.22 8.822-54.017 28.012-72.375 55.53 17.544 47.898 17.544 57.26 0 105.157 19.92 15.463 40.304 24.76 60.782 27.47-2.063-25.563-3.63-51.13 1.125-76.69-13.625-1.483-23.374-5.995-37-13.874V82.563c35.866 19.096 61.84 18.777 98.813 0v32.22c-13.364 6.497-21.886 11.16-35.25 13.218 3.614 25.568 3.48 51.15 1.375 76.72 18.644-3.265 37.236-12.113 55.5-26.845-14.353-47.897-14.355-57.26 0-105.156-16.982-28.008-47.453-46.633-72.97-55.532zm-129.594 8.218c-25.906 110.414-27.35 215.33-27.4 330.922-18.84-1.537-37.582-5.12-56.027-11.12v28.554h69.066c8.715 35.025 6.472 70.052-1.036 105.078h28.13c-7.195-35.026-8.237-70.053-.872-105.078h68.904v-28.555c-18.49 4.942-37.256 8.552-56.097 10.46.082-114.94 2.496-223.068-24.667-330.26zm89.47 202.375c0 117.27 25.517 233.342 120.155 257.97C446.62 464.716 462.72 345.374 462.72 227.78H222.28z"/></svg>

After

Width:  |  Height:  |  Size: 956 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="512" height="512"><path fill="#000" d="M256 16C123.5 16 16 123.5 16 256c0 132.6 107.5 240 240 240 132.6 0 240-107.4 240-240S388.6 16 256 16zm0 60c99.4 0 180 80.6 180 180s-80.6 180-180 180S76 355.4 76 256 156.6 76 256 76zm91.3 64.2c-6.5 0-12.5 2.4-16.8 8.2-52 70.1-69 96.5-106 169.8-8.4-11.1-65.6-72.4-93.9-94.1-14.2-10.9-41.3 27.2-31.6 37.1C142.6 306.1 220.1 406 232.7 405c21.4-1.7 75.1-136.8 148.8-233.7 8-10.4-15-31.3-34.2-31.1z"/></svg>

After

Width:  |  Height:  |  Size: 508 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 MiB

View File

@ -6,7 +6,7 @@ _**Warnung:** Das System befindet sich noch in der Entwicklung._
Gehe auf die Setup-Seite deiner Foundry VTT Instanz. Klicke im Reiter **Game Systems** auf den Button **Install System**. In dem dann geöffneten Dialog, unten in der Zeile **Manifest URL** den Link zur aktuellen (oder gewünschten) Version der _system.json_ eintragen und auf **Install** klicken:
https://github.com/michaelstein/foundry-vtt-system-midgard5/releases/download/v1.0.1/system.json
https://git.byroks.de/MidgardVTT-Entwicklung/foundry-vtt-system-midgard5/releases/download/v1.3.0/system.json
Danach kann eine Spielwelt mit dem System erstellt werden.
@ -32,7 +32,7 @@ Dieser Reiter enthält (mit Ausname von Zaubern) alle zu erlernenden Dinge des C
![Blaupausen für Gegenstände](compendium-items.de.png)
Es kann einfach per Drag'n'Drop die entsprechende Blaupause auf den Charakterbogen gezogen werden, um eine Fertigkeit/Fähigkeit/Sprache zu *lernen.* Alternativ kann auch der **Lernen** Button bei den **ungelernten Fertigkeiten** geklickt werden.
Es kann einfach per Drag'n'Drop die entsprechende Blaupause auf den Charakterbogen gezogen werden, um eine Fertigkeit/Fähigkeit/Sprache zu _lernen._ Alternativ kann auch der **Lernen** Button bei den **ungelernten Fertigkeiten** geklickt werden.
Um den **Fertigkeitswert** und die **Leiteigenschaft** einer Fertigkeit anzupassen, kann man auf die Fertigkeit klicken. Dann geht folgender Dialog auf:

View File

@ -1,5 +1,4 @@
{
"moduleName": "Midgard 5. Edition",
"repository": "https://github.com/Byroks/foundry-vtt-system-midgard5",
"rawURL": "https://raw.githubusercontent.com/Byroks/foundry-vtt-system-midgard5"
"repository": "https://git.byroks.de/MidgardVTT-Entwicklung/foundry-vtt-system-midgard5"
}

View File

@ -1,29 +1,28 @@
import * as gulp from "gulp"
import fs from "fs-extra"
import * as path from "path"
import archiver from "archiver"
import stringify from "json-stringify-pretty-compact"
import * as gulp from "gulp";
import fs from "fs-extra";
import * as path from "path";
import archiver from "archiver";
import stringify from "json-stringify-pretty-compact";
const sourcemaps = require('gulp-sourcemaps')
const uglify = require('gulp-uglify')
const concat = require("gulp-concat")
const buffer = require('vinyl-buffer')
const source = require('vinyl-source-stream')
const through = require('through2')
const jsonminify = require('gulp-jsonminify')
const merge2 = require('merge2')
const sourcemaps = require("gulp-sourcemaps");
const uglify = require("gulp-uglify");
const concat = require("gulp-concat");
const buffer = require("vinyl-buffer");
const source = require("vinyl-source-stream");
const through = require("through2");
const jsonminify = require("gulp-jsonminify");
const merge2 = require("merge2");
const git = require('gulp-git-streamed')
const git = require("gulp-git-streamed");
const loadJson = (path: string): any => {
try {
let str = fs.readFileSync(path).toString()
return JSON.parse(str)
}
catch {
throw Error("Unable to load " + path)
}
let str = fs.readFileSync(path).toString();
return JSON.parse(str);
} catch {
throw Error("Unable to load " + path);
}
};
import {
createLiteral,
@ -38,36 +37,37 @@ import {
TransformerFactory,
visitEachChild,
visitNode,
} from "typescript"
import less from "gulp-less"
} from "typescript";
import less from "gulp-less";
import Logger from "./source/utils/Logger"
import {ModuleData} from "@league-of-foundry-developers/foundry-vtt-types/src/foundry/common/packages.mjs"
import browserify from "browserify"
const tsify = require("tsify")
import Logger from "./source/utils/Logger";
import { ModuleData } from "@league-of-foundry-developers/foundry-vtt-types/src/foundry/common/packages.mjs";
import browserify from "browserify";
import { data } from "jquery";
const tsify = require("tsify");
const ts = require("gulp-typescript")
const ts = require("gulp-typescript");
const argv = require("yargs").argv
const argv = require("yargs").argv;
let distPath = "dist"
let distPath = "dist";
function getConfig() {
const configPath = path.resolve(process.cwd(), "foundryconfig.json")
let config
const configPath = path.resolve(process.cwd(), "foundryconfig.json");
let config;
if (fs.existsSync(configPath)) {
config = loadJson(configPath)
return config
config = loadJson(configPath);
return config;
} else {
return
return;
}
}
interface Manifest {
root: string
file: ModuleData
name: string
root: string;
file: ModuleData;
name: string;
}
const getManifest = (): Manifest | null => {
@ -75,237 +75,211 @@ const getManifest = (): Manifest | null => {
root: "",
// @ts-ignore
file: {},
name: ""
}
name: "",
};
if (fs.existsSync("source")) {
json.root = "source"
json.root = "source";
} else {
json.root = distPath
json.root = distPath;
}
const modulePath = path.join(json.root, "module.json")
const systemPath = path.join(json.root, "system.json")
const modulePath = path.join(json.root, "module.json");
const systemPath = path.join(json.root, "system.json");
if (fs.existsSync(modulePath)) {
json.file = loadJson(modulePath) as ModuleData
json.name = "module.json"
json.file = loadJson(modulePath) as ModuleData;
json.name = "module.json";
} else if (fs.existsSync(systemPath)) {
json.file = loadJson(systemPath) as ModuleData
json.name = "system.json"
json.file = loadJson(systemPath) as ModuleData;
json.name = "system.json";
} else {
return null
}
return json
return null;
}
return json;
};
const createTransformer = (): TransformerFactory<any> => {
/**
* @param {typescript.Node} node
*/
const shouldMutateModuleSpecifier = (node: Node): boolean => {
if (!isImportDeclaration(node) && !isExportDeclaration(node))
return false
if (node.moduleSpecifier === undefined)
return false
if (!isStringLiteral(node.moduleSpecifier))
return false
if (!node.moduleSpecifier.text.startsWith("./") && !node.moduleSpecifier.text.startsWith("../"))
return false
if (!isImportDeclaration(node) && !isExportDeclaration(node)) return false;
if (node.moduleSpecifier === undefined) return false;
if (!isStringLiteral(node.moduleSpecifier)) return false;
if (!node.moduleSpecifier.text.startsWith("./") && !node.moduleSpecifier.text.startsWith("../")) return false;
return path.extname(node.moduleSpecifier.text) === ""
}
return path.extname(node.moduleSpecifier.text) === "";
};
return (context: TransformationContext): TSTransformer<any> => {
return (node: Node) => {
function visitor(node: Node): Node {
if (shouldMutateModuleSpecifier(node)) {
if (isImportDeclaration(node)) {
const newModuleSpecifier = createLiteral(`${(node.moduleSpecifier as LiteralExpression).text}.js`)
return factory.updateImportDeclaration(node, node.decorators, node.modifiers, node.importClause, newModuleSpecifier, undefined)
const newModuleSpecifier = createLiteral(`${(node.moduleSpecifier as LiteralExpression).text}.js`);
return factory.updateImportDeclaration(node, node.decorators, node.modifiers, node.importClause, newModuleSpecifier, undefined);
} else if (isExportDeclaration(node)) {
const newModuleSpecifier = createLiteral(`${(node.moduleSpecifier as LiteralExpression).text}.js`)
return factory.updateExportDeclaration(node, node.decorators, node.modifiers, false, node.exportClause, newModuleSpecifier, undefined)
const newModuleSpecifier = createLiteral(`${(node.moduleSpecifier as LiteralExpression).text}.js`);
return factory.updateExportDeclaration(node, node.decorators, node.modifiers, false, node.exportClause, newModuleSpecifier, undefined);
}
}
return visitEachChild(node, visitor, context)
return visitEachChild(node, visitor, context);
}
return visitNode(node, visitor)
}
}
}
return visitNode(node, visitor);
};
};
};
const tsConfig = ts.createProject("tsconfig.json", {
getCustomTransformers: (_program: any) => ({
after: [createTransformer()],
}),
})
});
function buildTS() {
const debug = process.env.npm_lifecycle_event !== "package"
let res = tsConfig.src()
.pipe(sourcemaps.init())
.pipe(tsConfig())
const debug = process.env.npm_lifecycle_event !== "package";
let res = tsConfig.src().pipe(sourcemaps.init()).pipe(tsConfig());
return res.js
.pipe(sourcemaps.write('', { debug: debug, includeContent: true, sourceRoot: './ts/source' }))
.pipe(gulp.dest(distPath))
return res.js.pipe(sourcemaps.write("", { debug: debug, includeContent: true, sourceRoot: "./ts/source" })).pipe(gulp.dest(distPath));
}
const bundleModule = () => {
const debug = argv.dbg || argv.debug
const bsfy = browserify(path.join(__dirname, "source/index.ts"), { debug: debug })
return bsfy.on('error', Logger.err)
const debug = argv.dbg || argv.debug;
const bsfy = browserify(path.join(__dirname, "source/index.ts"), { debug: debug });
return bsfy
.on("error", Logger.err)
.plugin(tsify)
.bundle()
.pipe(source(path.join(distPath, "bundle.js")))
.pipe(buffer())
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(uglify())
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('./'))
}
.pipe(sourcemaps.write("./"))
.pipe(gulp.dest("./"));
};
const buildLess = () => {
return gulp.src("source/style/*.less")
.pipe(less())
.pipe(concat("bundle.css"))
.pipe(gulp.dest(distPath))
}
return gulp.src("source/style/*.less").pipe(less()).pipe(concat("bundle.css")).pipe(gulp.dest(distPath));
};
interface Pack {
root: string,
type: string,
name: string
root: string;
type: string;
name: string;
}
const buildPack = (pack: Pack): NodeJS.ReadWriteStream => {
return gulp.src(pack.root + "/" + pack.type + "/" + pack.name + "/*.json")
return gulp
.src(pack.root + "/" + pack.type + "/" + pack.name + "/*.json")
.pipe(jsonminify())
.pipe(concat(pack.name + ".db"))
.pipe(gulp.dest(distPath + "/" + pack.root + "/" + pack.type))
}
.pipe(gulp.dest(distPath + "/" + pack.root + "/" + pack.type));
};
const buildPacks = () => {
let packs: Pack[] = []
let packs: Pack[] = [];
const rootDir = "packs"
const packTypes = fs.readdirSync(rootDir).filter(p => fs.statSync(path.join(rootDir, p)).isDirectory())
packTypes.forEach(packType => {
const packDir = path.join(rootDir, packType)
const packNames = fs.readdirSync(packDir).filter(p => fs.statSync(path.join(packDir, p)).isDirectory())
packNames.forEach(packName => {
const rootDir = "packs";
const packTypes = fs.readdirSync(rootDir).filter((p) => fs.statSync(path.join(rootDir, p)).isDirectory());
packTypes.forEach((packType) => {
const packDir = path.join(rootDir, packType);
const packNames = fs.readdirSync(packDir).filter((p) => fs.statSync(path.join(packDir, p)).isDirectory());
packNames.forEach((packName) => {
packs.push({
name: packName,
type: packType,
root: rootDir
})
})
})
root: rootDir,
});
});
});
return merge2(packs.map(p => buildPack(p)))
}
return merge2(packs.map((p) => buildPack(p)));
};
const copyFiles = async () => {
const recursiveFileSearch = (dir: string, callback: (err: NodeJS.ErrnoException | null, res: Array<string>) => void) => {
let results: Array<string> = []
let results: Array<string> = [];
fs.readdir(dir, (err, list) => {
if (err)
return callback(err, results)
if (err) return callback(err, results);
let pending = list.length
if (!pending)
return callback(null, results)
let pending = list.length;
if (!pending) return callback(null, results);
for (let file of list) {
file = path.resolve(dir, file)
file = path.resolve(dir, file);
fs.stat(file, (err, stat) => {
if (stat && stat.isDirectory()) {
recursiveFileSearch(file, (err, res) => {
results = results.concat(res)
if (!--pending)
callback(null, results)
})
results = results.concat(res);
if (!--pending) callback(null, results);
});
} else {
results.push(file);
if (!--pending) callback(null, results);
}
else {
results.push(file)
if (!--pending)
callback(null, results)
}
})
}
})
});
}
});
};
try {
const modulePath = path.join("source", "module.json");
if (fs.existsSync(modulePath)) await fs.copyFile(modulePath, path.join(distPath, "module.json"));
const modulePath = path.join("source", "module.json")
if (fs.existsSync(modulePath))
await fs.copyFile(modulePath, path.join(distPath, "module.json"))
const systemPath = path.join("source/system.json");
if (fs.existsSync(systemPath)) await fs.copyFile(systemPath, path.join(distPath, "system.json"));
const systemPath = path.join("source/system.json")
if (fs.existsSync(systemPath))
await fs.copyFile(systemPath, path.join(distPath, "system.json"))
if (!fs.existsSync(path.resolve(__dirname, "assets")))
return Promise.resolve()
if (!fs.existsSync(path.resolve(__dirname, "assets"))) return Promise.resolve();
const filter = (src: string, dest: string): boolean => {
Logger.ok("Copying file: " + dest)
return true
}
Logger.ok("Copying file: " + dest);
return true;
};
await fs.copyFile(path.join("source", "template.json"), path.join(distPath, "template.json"))
await fs.copyFile(path.join("source", "template.json"), path.join(distPath, "template.json"));
fs.copySync(path.resolve(__dirname, "assets"), path.resolve(__dirname, distPath + "/assets"), { overwrite: true, filter })
fs.copySync(path.resolve(__dirname, "lang"), path.resolve(__dirname, distPath + "/lang"), { overwrite: true, filter })
fs.copySync(path.resolve(__dirname, "assets"), path.resolve(__dirname, distPath + "/assets"), { overwrite: true, filter });
fs.copySync(path.resolve(__dirname, "lang"), path.resolve(__dirname, distPath + "/lang"), { overwrite: true, filter });
//fs.copySync(path.resolve(__dirname, "packs"), path.resolve(__dirname, distPath + "/packs"), { overwrite: true, filter })
fs.copySync(path.resolve(__dirname, "templates"), path.resolve(__dirname, distPath + "/templates"), { overwrite: true, filter })
return Promise.resolve()
fs.copySync(path.resolve(__dirname, "templates"), path.resolve(__dirname, distPath + "/templates"), { overwrite: true, filter });
return Promise.resolve();
} catch (err) {
await Promise.reject(err)
}
await Promise.reject(err);
}
};
const cleanDist = async () => {
if (argv.dbg || argv.debug)
return
Logger.log("Cleaning dist file clutter")
if (argv.dbg || argv.debug) return;
Logger.log("Cleaning dist file clutter");
const files: string[] = []
const files: string[] = [];
const getFiles = async (dir: string) => {
const arr = await fs.promises.readdir(dir)
for(const entry of arr)
{
const fullPath = path.join(dir, entry)
const stat = await fs.promises.stat(fullPath)
if (stat.isDirectory())
await getFiles(fullPath)
else
files.push(fullPath)
}
const arr = await fs.promises.readdir(dir);
for (const entry of arr) {
const fullPath = path.join(dir, entry);
const stat = await fs.promises.stat(fullPath);
if (stat.isDirectory()) await getFiles(fullPath);
else files.push(fullPath);
}
};
await getFiles(path.resolve(distPath))
await getFiles(path.resolve(distPath));
for (const file of files) {
if (file.endsWith("bundle.js") || file.endsWith(".css") || file.endsWith("module.json"))
continue
if (file.endsWith("bundle.js") || file.endsWith(".css") || file.endsWith("module.json")) continue;
Logger.warn("Cleaning " + path.relative(process.cwd(), file))
await fs.promises.unlink(file)
}
Logger.warn("Cleaning " + path.relative(process.cwd(), file));
await fs.promises.unlink(file);
}
};
/**
* Watch for changes for each build step
*/
const buildWatch = () => {
gulp.watch("source/**/*.ts", { ignoreInitial: false }, gulp.series(buildTS, bundleModule))
gulp.watch("source/**/*.less", { ignoreInitial: false }, buildLess)
gulp.watch("packs", { ignoreInitial: false }, buildPacks)
gulp.watch(["assets", "lang", "templates", "source/*.json"], { ignoreInitial: false }, copyFiles)
}
gulp.watch("source/**/*.ts", { ignoreInitial: false }, gulp.series(buildTS, bundleModule));
gulp.watch("source/**/*.less", { ignoreInitial: false }, buildLess);
gulp.watch("packs", { ignoreInitial: false }, buildPacks);
gulp.watch(["assets", "lang", "templates", "source/*.json"], { ignoreInitial: false }, copyFiles);
};
/********************/
/* CLEAN */
@ -316,67 +290,63 @@ const buildWatch = () => {
* while ignoring source files
*/
const clean = async () => {
if (!fs.existsSync(distPath))
fs.mkdirSync(distPath)
if (!fs.existsSync(distPath)) fs.mkdirSync(distPath);
else {
// Attempt to remove the files
try {
fs.rmSync(distPath, { recursive: true, force: true })
fs.mkdirSync(distPath)
return Promise.resolve()
fs.rmSync(distPath, { recursive: true, force: true });
fs.mkdirSync(distPath);
return Promise.resolve();
} catch (err) {
await Promise.reject(err)
}
await Promise.reject(err);
}
}
};
const setTargetDir = async () => {
const dp = process.env.FOUNDRY_PATH
if (!dp)
throw Error("FOUNDRY_PATH not defined in environment")
const dp = process.env.FOUNDRY_PATH;
if (!dp) throw Error("FOUNDRY_PATH not defined in environment");
const name = getManifest()!.file.name ?? "midgard5"
distPath = path.join(dp, "Data", "systems", name)
}
const name = getManifest()!.file.name ?? "midgard5";
distPath = path.join(dp, "Data", "systems", name);
};
const linkUserData = async () => {
const name = getManifest()!.file.name
const name = getManifest()!.file.name;
let destDir
let destDir;
try {
if (fs.existsSync(path.resolve(".", distPath, "module.json")) || fs.existsSync(path.resolve(".", "source", "module.json"))) {
destDir = "modules"
destDir = "modules";
} else if (fs.existsSync(path.resolve(".", distPath, "system.json")) || fs.existsSync(path.resolve(".", "source", "system.json"))) {
destDir = "systems"
destDir = "systems";
} else {
throw Error(`Could not find module.json or system.json`)
throw Error(`Could not find module.json or system.json`);
}
let linkDir
const dataPath = process.env.FOUNDRY_PATH
let linkDir;
const dataPath = process.env.FOUNDRY_PATH;
if (dataPath) {
if (!fs.existsSync(path.join(dataPath, "Data")))
throw Error("User Data path invalid, no Data directory found")
linkDir = path.join(dataPath, "Data", destDir, name as string)
if (!fs.existsSync(path.join(dataPath, "Data"))) throw Error("User Data path invalid, no Data directory found");
linkDir = path.join(dataPath, "Data", destDir, name as string);
} else {
throw Error("FOUNDRY_PATH not defined in environment")
throw Error("FOUNDRY_PATH not defined in environment");
}
//if (argv.clean || argv.c) {
Logger.warn(`Removing build in ${linkDir}`)
fs.rmSync(linkDir, { recursive: true, force: true })
fs.mkdirSync(linkDir)
Logger.warn(`Removing build in ${linkDir}`);
fs.rmSync(linkDir, { recursive: true, force: true });
fs.mkdirSync(linkDir);
//}
Logger.ok(`Copying build to ${linkDir}`)
fs.copySync(path.resolve(distPath), linkDir, { overwrite: true })
Logger.ok(`Copying build to ${linkDir}`);
fs.copySync(path.resolve(distPath), linkDir, { overwrite: true });
return Promise.resolve()
return Promise.resolve();
} catch (err) {
await Promise.reject(err)
}
await Promise.reject(err);
}
};
/*********************/
/* PACKAGE */
@ -386,48 +356,51 @@ const linkUserData = async () => {
* Package build
*/
async function packageBuild() {
const manifest = getManifest()
const manifest = getManifest();
if (manifest === null) {
Logger.err("Manifest file could not be loaded.")
throw Error()
Logger.err("Manifest file could not be loaded.");
throw Error();
}
return new Promise((resolve, reject) => {
try {
// Remove the package dir without doing anything else
if (argv.clean || argv.c) {
Logger.warn("Removing all packaged files")
fs.rmSync(distPath, { force: true, recursive: true })
return
Logger.warn("Removing all packaged files");
fs.rmSync(distPath, { force: true, recursive: true });
return;
}
// Ensure there is a directory to hold all the packaged versions
if(!fs.existsSync(distPath))
fs.mkdirSync(distPath)
if (!fs.existsSync(distPath)) fs.mkdirSync(distPath);
// Initialize the zip file
const zipName = `${manifest.file.name}-v${manifest.file.version}.zip`
const zipFile = fs.createWriteStream(path.join(distPath, zipName))
const zip = archiver("zip", { zlib: { level: 9 } })
const zipName = `${manifest.file.name}-v${manifest.file.version}.zip`;
const zipFile = fs.createWriteStream(zipName);
const zip = archiver("zip", { zlib: { level: 9 } });
zipFile.on("close", () => {
Logger.ok(zip.pointer() + " total bytes")
Logger.ok(`Zip file ${zipName} has been written`)
return resolve(true)
})
Logger.ok(zip.pointer() + " total bytes");
Logger.ok(`Zip file ${zipName} has been written`);
return resolve(true);
});
zipFile.on("end", function () {
throw "Data has been drained";
});
zip.on("error", (err) => {
throw err
})
throw err;
});
zip.pipe(zipFile)
zip.pipe(zipFile);
zip.directory(path.join(process.cwd(), distPath), false)
return zip.finalize()
zip.directory(distPath, manifest.file.name);
return zip.finalize();
} catch (err) {
return reject(err)
return reject(err);
}
})
});
}
/*********************/
@ -438,116 +411,113 @@ async function packageBuild() {
* Update version and URLs in the manifest JSON
*/
const updateManifest = (cb: any) => {
const packageJson = loadJson("package.json")
const packageJson = loadJson("package.json");
const config = getConfig(),
manifest = getManifest(),
rawURL = config.rawURL,
repoURL = config.repository,
manifestRoot = manifest!.root
manifestRoot = manifest!.root;
if (!config)
cb(Error("foundryconfig.json not found"))
if (!config) cb(Error("foundryconfig.json not found"));
if (manifest === null) {
cb(Error("Manifest JSON not found"))
return
cb(Error("Manifest JSON not found"));
return;
}
if (!rawURL || !repoURL)
cb(Error("Repository URLs not configured in foundryconfig.json"))
if (!repoURL) cb(Error("Repository URLs not configured in foundryconfig.json"));
try {
const version = argv.update || argv.u
const version = argv.update || argv.u;
/* Update version */
const versionMatch = /^(\d{1,}).(\d{1,}).(\d{1,})$/
const currentVersion = manifest!.file.version
let targetVersion = ""
const versionMatch = /^(\d{1,}).(\d{1,}).(\d{1,})$/;
const currentVersion = manifest!.file.version;
let targetVersion = "";
if (!version) {
cb(Error("Missing version number"))
cb(Error("Missing version number"));
}
if (versionMatch.test(version)) {
targetVersion = version
targetVersion = version;
} else {
targetVersion = currentVersion.replace(versionMatch, (substring: string, major: string, minor: string, patch: string) => {
console.log(substring, Number(major) + 1, Number(minor) + 1, Number(patch) + 1)
console.log(substring, Number(major) + 1, Number(minor) + 1, Number(patch) + 1);
if (version === "major") {
return `${Number(major) + 1}.0.0`
return `${Number(major) + 1}.0.0`;
} else if (version === "minor") {
return `${major}.${Number(minor) + 1}.0`
return `${major}.${Number(minor) + 1}.0`;
} else if (version === "patch") {
return `${major}.${minor}.${Number(patch) + 1}`
return `${major}.${minor}.${Number(patch) + 1}`;
} else {
return ""
return "";
}
})
});
}
if (targetVersion === "") {
return cb(Error("Error: Incorrect version arguments."))
return cb(Error("Error: Incorrect version arguments."));
}
if (targetVersion === currentVersion) {
return cb(Error("Error: Target version is identical to current version."))
return cb(Error("Error: Target version is identical to current version."));
}
Logger.ok(`Updating version number to '${targetVersion}'`)
Logger.ok(`Updating version number to '${targetVersion}'`);
packageJson.version = targetVersion
manifest.file.version = targetVersion
packageJson.version = targetVersion;
manifest.file.version = targetVersion;
/* Update URLs */
const result = `${rawURL}/v${manifest.file.version}/${distPath}/${manifest.file.name}-v${manifest.file.version}.zip`
const result = `${repoURL}/releases/download`;
manifest.file.url = repoURL
manifest.file.manifest = `${rawURL}/master/${manifestRoot}/${manifest.name}`
manifest.file.download = result
manifest.file.url = repoURL;
manifest.file.manifest = `${result}/latest/${manifest.name}?token=2455375115b92bc8d87c93df7159eec232456f2d`;
manifest.file.download = `${result}/v${manifest.file.version}/${manifest.file.name}-v${manifest.file.version}.zip?token=2455375115b92bc8d87c93df7159eec232456f2d`;
const prettyProjectJson = stringify(manifest.file, {
maxLength: 35,
indent: "\t",
})
});
fs.writeFileSync("package.json", JSON.stringify(packageJson, null, '\t'))
fs.writeFileSync(path.join(manifest.root, manifest.name), prettyProjectJson, "utf8")
fs.writeFileSync("package.json", JSON.stringify(packageJson, null, "\t"));
fs.writeFileSync(path.join(manifest.root, manifest.name), prettyProjectJson, "utf8");
return cb()
return cb();
} catch (err) {
return cb(err)
}
return cb(err);
}
};
const gitTaskManifest = (cb: gulp.TaskFunctionCallback) => {
const manifest = getManifest()
if (!manifest)
return cb(Error("could not load manifest."))
return gulp.src([`package.json`, `source/module.json`])
const manifest = getManifest();
if (!manifest) return cb(Error("could not load manifest."));
return gulp
.src([`package.json`, `source/system.json`])
.pipe(git.add({ args: "--no-all -f" }))
.pipe(git.commit(`v${manifest.file.version}`, { args: "-a", disableAppendPaths: true }))
}
.pipe(git.commit(`v${manifest.file.version}`, { args: "-a", disableAppendPaths: true }));
};
const gitTaskBuild = (cb: gulp.TaskFunctionCallback) => {
const manifest = getManifest()
if (!manifest)
return cb(Error("could not load manifest."))
const manifest = getManifest();
if (!manifest) return cb(Error("could not load manifest."));
return gulp.src(`${distPath}/${manifest.file.name}-v${manifest.file.version}.zip`)
.pipe(git.checkout(`v${manifest.file.version}`, { args: '-b' }))
return gulp
.src(`${manifest.file.name}.zip`)
.pipe(git.checkout(`v${manifest.file.version}`, { args: "-b" }))
.pipe(git.add({ args: "--no-all -f" }))
.pipe(git.commit(`v${manifest.file.version}`, { args: "-a", disableAppendPaths: true }))
}
.pipe(git.commit(`v${manifest.file.version}`, { args: "-a", disableAppendPaths: true }));
};
const execBuild = gulp.parallel(buildTS, buildLess, buildPacks, copyFiles)
const execBuild = gulp.parallel(buildTS, buildLess, buildPacks, copyFiles);
exports.build = gulp.series(clean, execBuild, bundleModule)
exports.buildTarget = gulp.series(setTargetDir, clean, execBuild, bundleModule)
exports.watch = buildWatch
exports.watchTarget = gulp.series(setTargetDir, buildWatch)
exports.clean = clean
exports.link = linkUserData
exports.package = packageBuild
exports.update = updateManifest
//exports.publish = gulp.series(clean, updateManifest, execBuild, bundleModule, packageBuild, gitTaskManifest, gitTaskBuild)
exports.build = gulp.series(clean, execBuild, bundleModule);
exports.buildTarget = gulp.series(setTargetDir, clean, execBuild, bundleModule);
exports.watch = buildWatch;
exports.watchTarget = gulp.series(setTargetDir, buildWatch);
exports.clean = clean;
exports.link = linkUserData;
exports.package = packageBuild;
exports.update = updateManifest;
exports.publish = gulp.series(clean, updateManifest, execBuild, bundleModule, packageBuild, gitTaskManifest);

View File

@ -1,232 +1,466 @@
{
"ACTOR.TypeCharacter": "Charakter",
"ACTOR.TypeNpc": "Kreatur / Nichtspielerfigur",
"TYPES.Actor.character": "Charakter",
"TYPES.Actor.npc": "Kreatur / Nichtspielerfigur",
"ACTOR.TypeVehicle": "Transportmittel / Pferd etc.",
"ITEM.TypeItem": "Gegenstand",
"ITEM.TypeWeapon": "Waffe",
"ITEM.TypeDefensiveWeapon": "Verteidigungswaffe",
"ITEM.TypeArmor": "Rüstung",
"ITEM.TypeSpell": "Zauber",
"TYPES.Item.item": "Gegenstand",
"TYPES.Item.skill": "Fertigkeit",
"TYPES.Item.weapon": "Waffe",
"TYPES.Item.defensiveWeapon": "Verteidigungswaffe",
"TYPES.Item.armor": "Rüstung",
"TYPES.Item.spell": "Zauber",
"TYPES.Item.effect": "Aktiver Effekt",
"TYPES.Item.kampfkunst": "Kampfkunst",
"TYPES.Item.container": "Aufbewahrung",
"TYPES.Item.class": "Klasse",
"midgard5.doRoll": "Würfeln",
"midgard5.learn": "Lernen",
"midgard5": {
"phase-action": "Handlungsphase",
"phase-movement": "Bewegungsphase",
"no-encounter": "Kein Kampf",
"encounter-not-started": "Kein aktiver Kampf",
"initiative": "Initiative",
"actionrank": "Handlungsrang",
"midgard5.label": "Bezeichnung",
"midgard5.description": "Beschreibung",
"midgard5.attribute": "Leiteigenschaft",
"midgard5.skill": "Fertigkeit",
"midgard5.skill-value": "Fertigkeitswert",
"midgard5.fw": "FW",
"midgard5.bonus": "Bonus",
"midgard5.ew": "EW",
"midgard5.pp-short": "PP",
"midgard5.pp": "Praxispunkte",
"combat-join": "Kampf Beitreten/Handlungsrang zurücksetzen",
"combat-ranged": "Fernangriff",
"combat-spell": "Zaubern (10 Sec)",
"midgard5.item-value": "Wert",
"midgard5.item-quantity": "Menge",
"midgard5.item-onbody": "Am Körper",
"midgard5.item-ismagic": "Ist Magisch",
"time-duration": "Dauer",
"time-round": "Runde(n)",
"time-minute": "Minute(n)",
"time-hour": "Stunde(n)",
"time-limitless": "Unbegrenzt",
"midgard5.actor-lp": "Lebenspunkte",
"midgard5.actor-lp-short": "LP",
"midgard5.actor-ap": "Ausdauerpunkte",
"midgard5.actor-ap-short": "AP",
"midgard5.actor-st": "St",
"midgard5.actor-st-long": "Stärke",
"midgard5.actor-ko": "Ko",
"midgard5.actor-ko-long": "Konstitution",
"midgard5.actor-au": "Au",
"midgard5.actor-au-long": "Aussehen",
"midgard5.actor-gs": "Gs",
"midgard5.actor-gs-long": "Geschicklichkeit",
"midgard5.actor-in": "In",
"midgard5.actor-in-long": "Intelligenz",
"midgard5.actor-pa": "pA",
"midgard5.actor-pa-long": "persönliche Ausstrahlung",
"midgard5.actor-gw": "Gw",
"midgard5.actor-gw-long": "Gewandtheit",
"midgard5.actor-zt": "Zt",
"midgard5.actor-zt-long": "Zaubertalent",
"midgard5.actor-wk": "Wk",
"midgard5.actor-wk-long": "Willenskraft",
"doRoll": "Würfeln",
"learn": "Lernen",
"midgard5.aktuell": "Akt.",
"midgard5.maximum": "Max.",
"midgard5.attrvalue": "Wert",
"midgard5.movementRange": "Bewegungsweite",
"label": "Bezeichnung",
"description": "Beschreibung",
"Characteristic": "Merkmal",
"characteristics": "Merkmale",
"background": "Hintergrund",
"attribute": "Eigenschaft",
"attributes": "Eigenschaften",
"points": "Punkte",
"calculated-value": "Berechneter Wert",
"calculated-values": "Werte und Boni",
"midgard5.base_values": "Grundwerte",
"midgard5.skills": "Fertigkeiten",
"midgard5.gear": "Ausrüstung",
"midgard5.spells": "Zauber",
"skill": "Fertigkeit",
"skill-value": "Fertigkeitswert",
"fw": "FW",
"bonus": "Bonus",
"bonuses": "Boni",
"ew": "EW",
"pp-short": "PP",
"pp": "Praxispunkte",
"midgard5.class": "Klasse",
"midgard5.race": "Rasse",
"midgard5.magicUsing": "zauberkundig",
"midgard5.gender": "Geschlecht",
"midgard5.weight": "Gewicht",
"midgard5.height": "Größe",
"midgard5.shape": "Gestalt",
"midgard5.age": "Alter",
"midgard5.caste": "Stand",
"midgard5.occupation": "Beruf",
"midgard5.origin": "Heimat",
"midgard5.faith": "Glaube",
"item-value": "Wert",
"item-quantity": "Menge",
"item-onbody": "Am Körper",
"item-ismagic": "Ist Magisch",
"item-wealth": "Vermögenswert",
"item-weight": "Gewicht",
"item-abw": "ABW",
"item-abw-long": "Ausbrennwahrscheinlichkeit",
"midgard5.exp-overall": "Erfahrungsschatz",
"midgard5.exp-available": "Erfahrungspunkte",
"midgard5.grace": "Göttliche Gnade",
"midgard5.destiny": "Schicksalsgunst",
"midgard5.luckPoints": "Glückspunkte",
"actor-lp": "Lebenspunkte",
"actor-lp-short": "LP",
"actor-ap": "Ausdauerpunkte",
"actor-ap-short": "AP",
"actor-st": "St",
"actor-st-long": "Stärke",
"actor-ko": "Ko",
"actor-ko-long": "Konstitution",
"actor-au": "Au",
"actor-au-long": "Aussehen",
"actor-gs": "Gs",
"actor-gs-long": "Geschicklichkeit",
"actor-in": "In",
"actor-in-long": "Intelligenz",
"actor-pa": "pA",
"actor-pa-long": "persönliche Ausstrahlung",
"actor-gw": "Gw",
"actor-gw-long": "Gewandtheit",
"actor-zt": "Zt",
"actor-zt-long": "Zaubertalent",
"actor-wk": "Wk",
"actor-wk-long": "Willenskraft",
"actor-git": "GiT",
"actor-git-long": "Gifttolleranz",
"midgard5.akrobatik": "Akrobatik",
"midgard5.alchimie": "Alchimie",
"midgard5.anfuehren": "Anführen",
"midgard5.athletik": "Athletik",
"midgard5.balancieren": "Balancieren",
"midgard5.beidhaendigerKampf": "Beidhändiger Kampf",
"midgard5.beredsamkeit": "Beredsamkeit",
"midgard5.betaeuben": "Betäuben",
"midgard5.bootfahren": "Bootfahren",
"midgard5.ersteHilfe": "Erste Hilfe",
"midgard5.etikette": "Etikette",
"midgard5.fallenEntdecken": "Fallen entdecken",
"midgard5.fallenmechanik": "Fallenmechanik",
"midgard5.faelschen": "Fälschen",
"midgard5.fechten": "Fechten",
"midgard5.gassenwissen": "Gassenwissen",
"midgard5.gaukeln": "Gaukeln",
"midgard5.gelaendelauf": "Geländelauf",
"midgard5.geraetekunde": "Gerätekunde",
"midgard5.geschaeftssinn": "Geschäftssinn",
"midgard5.gluecksspiel": "Glücksspiel",
"midgard5.heilkunde": "Heilkunde",
"midgard5.kampfInVollruestung": "Kampf in Vollrüstung",
"midgard5.klettern": "Klettern",
"midgard5.landeskunde": "Landeskunde",
"midgard5.laufen": "Laufen",
"midgard5.lesenVonZauberschrift": "Lesen von Zauberschrift",
"midgard5.meditieren": "Meditieren",
"midgard5.menschenkenntnis": "Menschenkenntnis",
"midgard5.meucheln": "Meucheln",
"midgard5.musizieren": "Musizieren",
"midgard5.naturkunde": "Naturkunde",
"midgard5.pflanzenkunde": "Pflanzenkunde",
"midgard5.reiten": "Reiten",
"midgard5.reiterkampf": "Reiterkampf",
"midgard5.scharfschiessen": "Scharfschießen",
"midgard5.schleichen": "Schleichen",
"midgard5.schloesserOeffnen": "Schlösser öffnen",
"midgard5.schwimmen": "Schwimmen",
"midgard5.seilkunst": "Seilkunst",
"midgard5.spurensuche": "Spurensuche",
"midgard5.stehlen": "Stehlen",
"midgard5.tarnen": "Tarnen",
"midgard5.tauchen": "Tauchen",
"midgard5.tierkunde": "Tierkunde",
"midgard5.ueberleben": "Überleben",
"midgard5.verfuehren": "Verführen",
"midgard5.verhoeren": "Verhören",
"midgard5.verstellen": "Verstellen",
"midgard5.wagenlenken": "Wagenlenken",
"midgard5.zauberkunde": "Zauberkunde",
"aktuell": "Akt.",
"maximum": "Max.",
"attrvalue": "Wert",
"movementRange": "Bewegungsweite",
"midgard5.armor": "Rüstung",
"midgard5.defense": "Abwehr",
"midgard5.damageBonus": "Schadensbonus",
"midgard5.damageBonus-short": "SchB",
"midgard5.attackBonus": "Angriffsbonus",
"midgard5.attackBonus-short": "AnB",
"midgard5.defenseBonus": "Abwehrbonus",
"midgard5.defenseBonus-short": "AbB",
"midgard5.movementBonus": "Bewegunsbonus",
"midgard5.resistanceMind": "Resistenz Geist",
"midgard5.resistanceBody": "Resistenz Körper",
"midgard5.spellCasting": "Zaubern",
"midgard5.spellBonus": "Zauberbonus",
"midgard5.brawl": "Raufen",
"midgard5.poisonResistance": "Giftresistenz",
"midgard5.enduranceBonus": "Ausdauerbonus",
"base_values": "Grundwerte",
"skills": "Fertigkeiten",
"gear": "Ausrüstung",
"spells": "Zauber",
"effects": "Aktive Effekte",
"kampfkuenste": "Kampfkünste",
"combat": "Kampf",
"midgard5.new-skill": "Neue Fertigkeit",
"midgard5.special": "Spezial",
"midgard5.learned-skill": "Gelernte Fertigkeit",
"midgard5.language": "Sprache",
"midgard5.weapon-skill": "Waffenfertigkeit",
"midgard5.unlearned-skill": "Ungelernte Fertigkeit",
"midgard5.innate-ability": "Angeborene Fähigkeit",
"actor-name": "Figur",
"level": "Grad",
"class": "Typ",
"race": "Rasse",
"magicUsing": "Zauberkundig",
"gender": "Geschlecht",
"weight": "Gewicht",
"height": "Größe",
"shape": "Gestalt",
"age": "Alter",
"caste": "Stand",
"occupation": "Beruf",
"origin": "Heimat",
"faith": "Glaube",
"midgard5.base-damage": "Grundschaden",
"midgard5.defensive-weapon": "Verteidigungswaffe",
"midgard5.no-skill": "Keine Fertigkeit",
"midgard5.magic": "magisch",
"midgard5.rangedWeapon": "Schusswaffe",
"midgard5.assignItemToCharacter": "Füge Gegenstand einem Charakter hinzu, um Fähigkeit auwählen zu können",
"currency": "Geld",
"currency-gold": "Gold",
"currency-silver": "Silber",
"currency-copper": "Kupfer",
"currency-wealth": "Vermögen in GS",
"currency-available": "verfügbares Vermögen",
"hoard": "aktueller Hort",
"hoardMin": "benötigter Mindesthort",
"hoard-next": "Hort für nächsten Grad",
"hoarded": "Hort",
"midgard5.pw": "Prüfwurf",
"midgard5.attack": "Angriff",
"midgard5.damage": "Schaden",
"no-container": "Ohne",
"midgard5.spell-process-none": "Ohne",
"midgard5.spell-process-beherrschen": "Beherrschen",
"midgard5.spell-process-bewegen": "Bewegen",
"midgard5.spell-process-erkennen": "Erkennen",
"midgard5.spell-process-erschaffen": "Erschaffen",
"midgard5.spell-process-formen": "Formen",
"midgard5.spell-process-veraendern": "Verändern",
"midgard5.spell-process-zerstoeren": "Zerstören",
"midgard5.spell-process-wundertat": "Wundertat",
"midgard5.spell-process-dweomer": "Dweomer",
"midgard5.spell-process-zauberlied": "Zauberlied",
"midgard5.spell-process-salz": "Salz",
"midgard5.spell-process-thaumagraphie": "Thaumagraphie",
"midgard5.spell-process-beschwoeren": "Beschwören",
"midgard5.spell-process-nekromantie": "Nekromantie",
"midgard5.spell-process-thaumatherapie": "Thaumatherapie",
"midgard5.spell-process-zaubermittel": "Zaubermittel",
"midgard5.spell-process-zauberschutz": "Zauberschutz",
"encumbrance": "Getragene Last",
"load": "Normallast",
"heavy-load": "Schwere Last",
"thrust-load": "Schublast",
"load-max": "Höchstlast",
"capacity": "Tragkraft",
"midgard5.spell-type-gedanke": "Gedanke",
"midgard5.spell-type-geste": "Geste",
"midgard5.spell-type-wort": "Wort",
"exp-overall": "Erfahrungsschatz",
"exp-available": "Erfahrungspunkte",
"grace": "Göttliche Gnade",
"destiny": "Schicksalsgunst",
"luckPoints": "Glückspunkte",
"midgard5.spell-target-umgebung": "Umgebung",
"midgard5.spell-target-geist": "Geist",
"midgard5.spell-target-koerper": "Körper",
"abrichten": "Abrichten",
"akrobatik": "Akrobatik",
"alchimie": "Alchimie",
"anfuehren": "Anführen",
"askese": "Askese",
"astrologie": "Astrologie",
"athletik": "Athletik",
"balancieren": "Balancieren",
"beidhaendigerKampf": "Beidhändiger Kampf",
"bergreiten": "Bergreiten",
"beredsamkeit": "Beredsamkeit",
"betaeuben": "Betäuben",
"betaeubungsgriff": "Betäubungsgriff",
"bildendeKuensteA": "Bildende Künste (Architektur)",
"bildendeKuensteB": "Bildende Künste (Bildhauerei)",
"bildendeKuensteG": "Bildende Künste (Grafik)",
"bildendeKuensteM": "Bildende Künste (Malerei)",
"bootfahren": "Bootfahren",
"dickhaeuterLenken": "Dickhäuter lenken",
"ersteHilfe": "Erste Hilfe",
"etikette": "Etikette",
"fallenEntdecken": "Fallen entdecken",
"fallenmechanik": "Fallenmechanik",
"faelschen": "Fälschen",
"fangen": "Fangen",
"fechten": "Fechten",
"fechtkunst": "Fechtkunst",
"feueralchimie": "Feueralchimie",
"gassenwissen": "Gassenwissen",
"gaukeln": "Gaukeln",
"gelaendelauf": "Geländelauf",
"geraetekunde": "Gerätekunde",
"geschaeftssinn": "Geschäftssinn",
"gluecksspiel": "Glücksspiel",
"heilkunde": "Heilkunde",
"kampfInVollruestung": "Kampf in Vollrüstung",
"kampfInSchlachtreihe": "Kampf in Schlachtreihe",
"kampfkunst": "Kampfkunst",
"kido": "Kido",
"klettern": "Klettern",
"landeskunde": "Landeskunde",
"laufen": "Laufen",
"lesenVonZauberschrift": "Lesen von Zauberschrift",
"lesenVonZauberrunen": "Lesen von Zauberrunen",
"meditieren": "Meditieren",
"menschenkenntnis": "Menschenkenntnis",
"meucheln": "Meucheln",
"musizierenFloete": "Musizieren (Flöten)",
"musizierenBlas": "Musizieren (Blasinstrumente)",
"musizierenRythmus": "Musizieren (Rythmusinstrumente)",
"musizierenStreich": "Musizieren (Streichinstrumente)",
"musizierenZupf": "Musizieren (Zupfinstrumente)",
"naturkunde": "Naturkunde",
"ninjutsu": "NinJutsu",
"orakelkunst": "Orakelkunst",
"pflanzenkunde": "Pflanzenkunde",
"raunen": "Raunen",
"reiten": "Reiten",
"reiterkampf": "Reiterkampf",
"rutengehen": "Rutengehen",
"scharfschiessen": "Scharfschießen",
"schiesskunst": "Schießkunst",
"schleichen": "Schleichen",
"schloesserOeffnen": "Schlösser öffnen",
"schmerzErtragen": "Schmerzen ertragen",
"schwimmen": "Schwimmen",
"seilkunst": "Seilkunst",
"selbstkontrolle": "Selbstkontrolle",
"singen": "Singen",
"skifahren": "Skifahren",
"spinnengang": "Spinnengang",
"speerfechten": "Speerfechten",
"spurensuche": "Spurensuche",
"stehlen": "Stehlen",
"taitschi": "TaiTschi",
"tarnen": "Tarnen",
"tanzen": "Tanzen",
"tauchen": "Tauchen",
"thaumagraphie": "Thaumagraphie",
"thaumalogie": "Thaumalogie",
"tierkunde": "Tierkunde",
"ueberlebenWald": "Überleben (Wald)",
"ueberlebenSteppe": "Überleben (Steppe)",
"ueberlebenGebirge": "Überleben (Gebirge)",
"verfuehren": "Verführen",
"verhoeren": "Verhören",
"verstellen": "Verstellen",
"volkstanz": "Volkstanz",
"wagenlenken": "Wagenlenken",
"wahrsagen": "Wahrsagen",
"wasserkampf": "Wasserkampf",
"zauberkunde": "Zauberkunde",
"midgard5.spell-type": "Art",
"midgard5.spell-process": "Prozess",
"midgard5.spell-castDuration": "Zauberdauer",
"midgard5.spell-range": "Reichweite",
"midgard5.spell-effectTarget": "Wirkunsziel",
"midgard5.spell-effectArea": "Wirkungsbereich",
"midgard5.spell-effectDuration": "Wirkungsdauer",
"midgard5.spell-origin": "Ursprung",
"armor": "Rüstung",
"defense": "Abwehr",
"damageBonus": "Schadensbonus",
"damageBonus-short": "SchB",
"attackBonus": "Angriffsbonus",
"attackBonus-short": "AnB",
"defenseBonus": "Abwehrbonus",
"defenseBonus-short": "AbB",
"movementBonus": "Bewegunsbonus",
"resistanceMind": "Resistenz Geist",
"resistanceBody": "Resistenz Körper",
"spellCasting": "Zaubern",
"spellBonus": "Zauberbonus",
"brawl": "Raufen",
"poisonResistance": "Gifttolleranz",
"enduranceBonus": "Ausdauerbonus",
"lpProtection": "Rüstungsschutz (LP)",
"apProtection": "Rüstungsschutz (AP)",
"deprivation": "Zähigkeit",
"deprivations": "Entbehrungen",
"deprivationCold": "Zähigkeit Kälte",
"deprivationHeat": "Zähigkeit Hitze",
"deprivationFood": "Zähigkeit Durst/Hunger",
"midgard5.mod-operation-add100": "Addieren (max 100)",
"midgard5.mod-operation-add": "Addieren",
"midgard5.mod-operation-set": "Basiswert",
"midgard5.mod-operation-fixed": "Fester Wert",
"new-skill": "Neue Fertigkeit",
"special": "Spezial",
"learned-skill": "Gelernte Fertigkeit",
"learned-skills": "Gelernte Fertigkeiten",
"language": "Sprache",
"languages": "Sprachen",
"writings": "Schriften",
"weapon-skill": "Waffenfertigkeit",
"weapon-skills": "Waffenfertigkeiten",
"unlearned-skill": "Ungelernte Fertigkeit",
"unlearned-skills": "Ungelernte Fertigkeiten",
"innate-ability": "Angeborene/Besondere Fähigkeit",
"innate-abilities": "Angeborene und besondere Fähigkeiten",
"midgard5.mod-stat-defenseBonus": "Abwehrbonus",
"midgard5.mod-stat-attackBonus": "Angriffsbonus",
"midgard5.mod-stat-damageBonus": "Schadensbonus",
"midgard5.mod-stat-movement": "Bewegung",
"midgard5.mod-stat-resistanceMind": "Resistenz Geist",
"midgard5.mod-stat-resistanceBody": "Resistenz Körper",
"midgard5.mod-stat-spellCasting": "Zaubern",
"midgard5.mod-stat-brawl": "Raufen",
"midgard5.mod-stat-poisonResistance": "Giftresistenz",
"midgard5.mod-stat-lp": "Lebenspunkte",
"midgard5.mod-stat-ap": "Ausdauerpunkte",
"base-damage": "Grundschaden",
"weapon": "Waffe",
"weapons": "Waffen",
"defensive-weapon": "Verteidigungswaffe",
"defensive-weapons": "Verteidigungswaffen",
"no-skill": "Keine Fertigkeit",
"magic": "magisch",
"valuable": "Vermögen",
"equipped": "Ausgerüstet",
"active": "Aktiv",
"rangedWeapon": "Schusswaffe",
"assignItemToCharacter": "Füge Gegenstand einem Charakter hinzu, um hier etwas auswählen zu können",
"showAll": "Alle anzeigen",
"showUnlearned": "Ungelernte Fertigkeiten",
"wealthAndWeight": "Vermögen und Lasten",
"itemsInContainers": "Gegenstände in Aufbewahrung",
"allItems": "Alle Gegenstände",
"midgard5.mod-type": "Typ der Modifikation",
"midgard5.mod-id": "Was soll modifiziert werden",
"midgard5.mod-operation": "Wie soll modifiziert werden",
"midgard5.mod-value": "Wert",
"pw": "Prüfwurf",
"attack": "Angriff",
"damage": "Schaden",
"midgard5.type": "Typ",
"midgard5.formula": "Formel",
"midgard5.roll": "Wurf"
"skill-goup-alltag": "Alltag",
"skill-goup-freiland": "Freiland",
"skill-goup-halbwelt": "Halbwelt",
"skill-goup-kampf": "Kampf",
"skill-goup-koerper": "Körper",
"skill-goup-sozial": "Sozial",
"skill-goup-unterwelt": "Unterwelt",
"skill-goup-waffen": "Waffen",
"skill-goup-wissen": "Wissen",
"spell-process-none": "Ohne",
"spell-process-artefakte": "Artefakte",
"spell-process-beherrschen": "Beherrschen",
"spell-process-bewegen": "Bewegen",
"spell-process-beschwoeren": "Beschwören",
"spell-process-blutmagie": "Blutmagie",
"spell-process-chaoswunder": "Chaoswunder",
"spell-process-dweomer": "Dweomer",
"spell-process-erkennen": "Erkennen",
"spell-process-erschaffen": "Erschaffen",
"spell-process-erhaltung": "Erhaltung",
"spell-process-formen": "Formen",
"spell-process-finstere_magie": "Finstere Magie",
"spell-process-kampfverse": "Kampfverse",
"spell-process-namensmagie": "Namensmagie",
"spell-process-nekromantie": "Nekromantie",
"spell-process-runenstaebe": "Runenstäbe",
"spell-process-thaumatherapie": "Thaumatherapie",
"spell-process-thaumagraphie": "Thaumagraphie",
"spell-process-veraendern": "Verändern",
"spell-process-vigilsignien": "Vigilsignien",
"spell-process-wundertat": "Wundertat",
"spell-process-wilder_dweomer": "Wilder Dweomer",
"spell-process-zerstoeren": "Zerstören",
"spell-process-zauberlied": "Zauberlieder",
"spell-process-zaubersalz": "Zaubersalze",
"spell-process-zaubermittel": "Zaubermittel",
"spell-process-zauberschutz": "Zauberschutz",
"spell-process-zauberrunen": "Zauberrunen",
"spell-process-zaubersiegel": "Zaubersiegel",
"spell-process-zaubertaenze": "Zaubertänze",
"spell-process-zauberblaetter": "Zauberblätter",
"spell-type-gedanke": "Gedanke",
"spell-type-geste": "Geste",
"spell-type-wort": "Wort",
"spell-target-umgebung": "Umgebung",
"spell-target-geist": "Geist",
"spell-target-koerper": "Körper",
"spell-type": "Art",
"spell-process": "Prozess",
"spell-castDuration": "Zauberdauer",
"spell-castDuration-short": "Zd",
"spell-range": "Reichweite",
"spell-range-short": "Rw",
"spell-effectTarget": "Wirkunsziel",
"spell-effectTarget-short": "Wz",
"spell-effectArea": "Wirkungsbereich",
"spell-effectArea-short": "Wb",
"spell-effectDuration": "Wirkungsdauer",
"spell-effectDuration-short": "Wd",
"spell-origin": "Ursprung",
"spell-agens": "Agens",
"spell-reagens": "Reagens",
"spell-material": "Zaubermaterial",
"spell-rank": "Stufe",
"kampfkunst-type": "Form",
"kampfkunst-variante": "Variante",
"kampfkunst-variante-short": "Var",
"kampfkunst-ep": "Erfahrungspunkte",
"kampfkunst-rank": "Stufe der Technik",
"kampfkunst-weapon": "Waffengruppe",
"kampfkunst-enemy": "Einschränkungen durch Art der Gegner",
"kampfkunst-type-angriff": "Angriff",
"kampfkunst-type-verteidigung": "Verteidigung",
"kampfkunst-type-finte": "Finte",
"kampfkunst-type-geist": "Geistestechnik",
"kampfkunst-type-schießkunst": "Schießkunst",
"kampfkunst-type-fechtkunst": "Fechtkunst",
"kampfkunst-variante-anstuermen": "Anstürmen",
"kampfkunst-variante-attackieren": "Attackieren",
"kampfkunst-variante-entwaffnen": "Entwaffnen",
"kampfkunst-variante-fechten": "Fechten",
"kampfkunst-variante-schusstechnik": "Schusstechnik",
"kampfkunst-variante-finten": "Finten",
"kampfkunst-variante-geistestechnik": "Geistestechnik",
"kampfkunst-variante-verteidigung": "Verteidigung",
"kido-type": "KiDo Form",
"kido-variante": "KiDo Variante",
"kido-color": "Kampfstilfarbe",
"kido-style": "Art der Technik",
"kido-rank": "Stufe der Technik",
"kido-grade": "Ausbildungsgrad",
"kido-enemy": "Einschränkungen durch Art der Gegner",
"kido-weapon": "Waffengruppe",
"kido-type-angriff": "Kido Angriff",
"kido-type-verteidigung": "Kido Verteidigung",
"kido-type-finte": "Kido Finte",
"kido-type-leib": "Kido Leibestechnik",
"kido-variante-anspringen": "Anspringen",
"kido-variante-attackieren": "Attackieren",
"kido-variante-entwaffnen": "Entwaffnen",
"kido-variante-werfen": "Werfen",
"kido-variante-ausweichen": "Ausweichen",
"kido-variante-blockieren": "Blockieren",
"kido-variante-bewegen": "Bewegen",
"kido-variante-kontrollieren": "Kontrollieren",
"kido-variante-finte": "Finte",
"mod-operation-add100": "Addieren (max 100)",
"mod-operation-roll": "Wurf Modifikation",
"mod-operation-add": "Addieren",
"mod-operation-set": "Basiswert",
"mod-operation-fixed": "Fester Wert",
"mod-operation-subtract": "Subtrahieren",
"mod-operation-multiply": "Multiplizieren",
"mod-operation-division": "Dividieren",
"mod-stat-defenseBonus": "Abwehrbonus",
"mod-stat-attackBonus": "Angriffsbonus",
"mod-stat-damageBonus": "Schadensbonus",
"mod-stat-movement": "Bewegung",
"mod-stat-resistanceMind": "Resistenz Geist",
"mod-stat-resistanceBody": "Resistenz Körper",
"mod-stat-spellCasting": "Zaubern",
"mod-stat-brawl": "Raufen",
"mod-stat-poisonResistance": "Gifttolleranz",
"mod-stat-lp": "Lebenspunkte",
"mod-stat-ap": "Ausdauerpunkte",
"mod-stat-lpProtection": "Rüstungsschutz (LP)",
"mod-stat-apProtection": "Rüstungsschutz (AP)",
"mod-stat-deprivationCold": "Entbehrungen Kälte",
"mod-stat-deprivationHeat": "Entbehrungen Hitze",
"mod-stat-deprivationFood": "Entbehrungen Durst/Hunger",
"mod-type": "Typ der Modifikation",
"mod-id": "Was soll modifiziert werden",
"mod-operation": "Wie soll modifiziert werden",
"mod-value": "Wert",
"type": "Typ",
"formula": "Formel",
"roll": "Wurf",
"chat": {
"luckPoint": "Glückspunkt",
"destiny": "Schicksalsgunst",
"modify": "Nachträglich",
"cancel": "Abbrechen",
"roll": "Würfeln",
"reroll": "Neuwürfeln",
"options": {
"modifier": "Wurfmodifikator",
"difficulty": "Erfolg",
"rollMode": "Würfelmodus"
}
}
}
}

View File

@ -1,6 +1,6 @@
{
"name": "foundry-system-midgard5",
"version": "1.2.0",
"version": "2.7.2",
"description": "",
"main": "index.js",
"scripts": {
@ -13,7 +13,7 @@
"build:watch:target": "gulp watchTarget",
"clean": "gulp clean && gulp link --clean"
},
"author": "Simon Gustavs",
"author": "Byroks",
"license": "MIT",
"devDependencies": {
"@babel/core": "^7.15.0",
@ -54,5 +54,8 @@
"vinyl-buffer": "^1.0.1",
"vinyl-source-stream": "^2.0.0",
"yargs": "^17.1.1"
},
"dependencies": {
"handlebars-helpers": "^0.10.0"
}
}

View File

@ -1,472 +0,0 @@
{
"name": "Grad 01",
"type": "character",
"img": "icons/svg/mystery-man.svg",
"system": {
"lp": {
"value": 15,
"min": 0,
"max": 15
},
"ap": {
"value": 20,
"min": 0,
"max": 20
},
"attributes": {
"st": {
"value": 50,
"bonus": 0
},
"gs": {
"value": 50,
"bonus": 0
},
"gw": {
"value": 50,
"bonus": 0
},
"ko": {
"value": 50,
"bonus": 0
},
"in": {
"value": 50,
"bonus": 0
},
"zt": {
"value": 50,
"bonus": 0
},
"au": {
"value": 50,
"bonus": 0
},
"pa": {
"value": 50,
"bonus": 0
},
"wk": {
"value": 50,
"bonus": 0
}
},
"info": {
"description": "",
"class": "",
"race": "",
"magicUsing": false,
"gender": "",
"weight": "",
"height": "",
"shape": "",
"age": "",
"caste": "",
"occupation": "",
"origin": "",
"faith": ""
},
"es": 0,
"ep": 0,
"gg": 0,
"sg": 0,
"gp": 2,
"skills": {
"general": {
"akrobatik": {
"fw": 6,
"attribute": "gw",
"initial": 8,
"pp": 0
},
"alchimie": {
"fw": 0,
"attribute": "in",
"initial": 8,
"pp": 0
},
"anfuehren": {
"fw": 6,
"attribute": "pa",
"initial": 8,
"pp": 0
},
"athletik": {
"fw": 0,
"attribute": "st",
"initial": 8,
"pp": 0
},
"balancieren": {
"fw": 6,
"attribute": "gw",
"initial": 8,
"pp": 0
},
"beidhaendigerKampf": {
"fw": 0,
"attribute": "gs",
"initial": 8,
"pp": 0
},
"beredsamkeit": {
"fw": 3,
"attribute": "pa",
"initial": 8,
"pp": 0
},
"betaeuben": {
"fw": 6,
"attribute": "gs",
"initial": 8,
"pp": 0
},
"bootfahren": {
"fw": 3,
"attribute": "gs",
"initial": 8,
"pp": 0
},
"ersteHilfe": {
"fw": 0,
"attribute": "gs",
"initial": 8,
"pp": 0
},
"etikette": {
"fw": 0,
"attribute": "in",
"initial": 8,
"pp": 0
},
"fallenEntdecken": {
"fw": 0,
"attribute": "in",
"initial": 8,
"pp": 0
},
"fallenmechanik": {
"fw": 0,
"attribute": "gs",
"initial": 8,
"pp": 0
},
"faelschen": {
"fw": 0,
"attribute": "gs",
"initial": 8,
"pp": 0
},
"fechten": {
"fw": 0,
"attribute": "gs",
"initial": 8,
"pp": 0
},
"gassenwissen": {
"fw": 0,
"attribute": "in",
"initial": 8,
"pp": 0
},
"gaukeln": {
"fw": 0,
"attribute": "gs",
"initial": 8,
"pp": 0
},
"gelaendelauf": {
"fw": 6,
"attribute": "gw",
"initial": 8,
"pp": 0
},
"geraetekunde": {
"fw": 0,
"attribute": "in",
"initial": 8,
"pp": 0
},
"geschaeftssinn": {
"fw": 0,
"attribute": "in",
"initial": 8,
"pp": 0
},
"gluecksspiel": {
"fw": 0,
"attribute": "gs",
"initial": 8,
"pp": 0
},
"heilkunde": {
"fw": 0,
"attribute": "in",
"initial": 8,
"pp": 0
},
"kampfInVollruestung": {
"fw": 0,
"attribute": "st",
"initial": 8,
"pp": 0
},
"klettern": {
"fw": 6,
"attribute": "st",
"initial": 8,
"pp": 0
},
"landeskunde": {
"fw": 6,
"attribute": "in",
"initial": 8,
"pp": 0
},
"laufen": {
"fw": 0,
"attribute": "ko",
"initial": 8,
"pp": 0
},
"lesenVonZauberschrift": {
"fw": 0,
"attribute": "in",
"initial": 8,
"pp": 0
},
"meditieren": {
"fw": 0,
"attribute": "wk",
"initial": 8,
"pp": 0
},
"menschenkenntnis": {
"fw": 3,
"attribute": "in",
"initial": 8,
"pp": 0
},
"meucheln": {
"fw": 0,
"attribute": "gs",
"initial": 8,
"pp": 0
},
"musizieren": {
"fw": 0,
"attribute": "gs",
"initial": 8,
"pp": 0
},
"naturkunde": {
"fw": 0,
"attribute": "in",
"initial": 8,
"pp": 0
},
"pflanzenkunde": {
"fw": 0,
"attribute": "in",
"initial": 8,
"pp": 0
},
"reiten": {
"fw": 6,
"attribute": "gw",
"initial": 8,
"pp": 0
},
"reiterkampf": {
"fw": 0,
"attribute": "gw",
"initial": 8,
"pp": 0
},
"scharfschiessen": {
"fw": 0,
"attribute": "gs",
"initial": 8,
"pp": 0
},
"schleichen": {
"fw": 3,
"attribute": "gw",
"initial": 8,
"pp": 0
},
"schloesserOeffnen": {
"fw": 0,
"attribute": "gs",
"initial": 8,
"pp": 0
},
"schwimmen": {
"fw": 3,
"attribute": "gw",
"initial": 8,
"pp": 0
},
"seilkunst": {
"fw": 3,
"attribute": "gs",
"initial": 8,
"pp": 0
},
"spurensuche": {
"fw": 0,
"attribute": "in",
"initial": 8,
"pp": 0
},
"stehlen": {
"fw": 3,
"attribute": "gs",
"initial": 8,
"pp": 0
},
"tarnen": {
"fw": 3,
"attribute": "gw",
"initial": 8,
"pp": 0
},
"tauchen": {
"fw": 6,
"attribute": "ko",
"initial": 8,
"pp": 0
},
"tierkunde": {
"fw": 0,
"attribute": "in",
"initial": 8,
"pp": 0
},
"ueberleben": {
"fw": 6,
"attribute": "in",
"initial": 8,
"pp": 0
},
"verfuehren": {
"fw": 3,
"attribute": "pa",
"initial": 8,
"pp": 0
},
"verhoeren": {
"fw": 3,
"attribute": "pa",
"initial": 8,
"pp": 0
},
"verstellen": {
"fw": 3,
"attribute": "pa",
"initial": 8,
"pp": 0
},
"wagenlenken": {
"fw": 3,
"attribute": "gs",
"initial": 8,
"pp": 0
},
"zauberkunde": {
"fw": 0,
"attribute": "in",
"initial": 8,
"pp": 0
}
}
},
"calc": {}
},
"prototypeToken": {
"name": "Spielfigur",
"displayName": 0,
"actorLink": false,
"texture": {
"src": "icons/svg/mystery-man.svg",
"scaleX": 1,
"scaleY": 1,
"offsetX": 0,
"offsetY": 0,
"rotation": 0,
"tint": null
},
"width": 1,
"height": 1,
"lockRotation": false,
"rotation": 0,
"alpha": 1,
"disposition": -1,
"displayBars": 0,
"bar1": {
"attribute": "lp"
},
"bar2": {
"attribute": "ap"
},
"light": {
"alpha": 0.5,
"angle": 360,
"bright": 0,
"color": null,
"coloration": 1,
"dim": 0,
"attenuation": 0.5,
"luminosity": 0.5,
"saturation": 0,
"contrast": 0,
"shadows": 0,
"animation": {
"type": null,
"speed": 5,
"intensity": 5,
"reverse": false
},
"darkness": {
"min": 0,
"max": 1
}
},
"sight": {
"enabled": false,
"range": null,
"angle": 360,
"visionMode": "basic",
"color": null,
"attenuation": 0.1,
"brightness": 0,
"saturation": 0,
"contrast": 0
},
"detectionModes": [],
"flags": {},
"randomImg": false
},
"items": [],
"effects": [],
"flags": {
"core": {
"sourceId": "Actor.25UihsoT43jms4Rx"
}
},
"_stats": {
"systemId": "midgard5",
"systemVersion": "1.1.0",
"coreVersion": "10.291",
"createdTime": 1681861642287,
"modifiedTime": 1681862257893,
"lastModifiedBy": "Fphp3NQlJ6KWctyq"
},
"folder": null,
"sort": 0,
"ownership": {
"default": 0,
"Fphp3NQlJ6KWctyq": 3
},
"_id": "k21WA0JziDJ7yJ1U"
}

1
packs/empty.md Normal file
View File

@ -0,0 +1 @@
JSON files for ompendium packs can be added here

View File

@ -1,49 +0,0 @@
{
"name": "Fernkampfwaffe",
"type": "weapon",
"img": "icons/svg/item-bag.svg",
"data": {
"description": "",
"stats": {
"damageBonus": 0,
"attackBonus": 0,
"defenseBonus": 0,
"movementBonus": 0,
"resistanceMind": 0,
"resistanceBody": 0,
"spellBonus": 0
},
"equippable": false,
"equipped": true,
"value": 0,
"magic": false,
"special": false,
"ranged": true,
"skillId": "",
"damageBase": "1d6",
"rolls": {
"formulas": {
"0": {
"formula": "1d20 + @i.calc.fw + @i.calc.bonus + @i.calc.special + @c.calc.stats.attackBonus.value + @i.stats.attackBonus",
"label": "Angriff",
"enabled": true
},
"1": {
"formula": "@i.damageBase + @i.stats.damageBonus",
"label": "Schaden",
"enabled": true
}
},
"output": ""
},
"calc": {}
},
"effects": [],
"folder": null,
"sort": 0,
"permission": {
"default": 0,
"XD0IpWT6bN4AJiYQ": 3
},
"_id": "h1inVuRJQI42JTCs"
}

View File

@ -1,69 +0,0 @@
{
"name": "Gewöhnliche Fertigkeit",
"type": "skill",
"img": "icons/svg/item-bag.svg",
"data": {
"description": "",
"attributes": {
"st": {
"short": "midgard5.actor-st",
"long": "midgard5.actor-st-long"
},
"gs": {
"short": "midgard5.actor-gs",
"long": "midgard5.actor-gs-long"
},
"gw": {
"short": "midgard5.actor-gw",
"long": "midgard5.actor-gw-long"
},
"ko": {
"short": "midgard5.actor-ko",
"long": "midgard5.actor-ko-long"
},
"in": {
"short": "midgard5.actor-in",
"long": "midgard5.actor-in-long"
},
"zt": {
"short": "midgard5.actor-zt",
"long": "midgard5.actor-zt-long"
},
"au": {
"short": "midgard5.actor-au",
"long": "midgard5.actor-au-long"
},
"pa": {
"short": "midgard5.actor-pa",
"long": "midgard5.actor-pa-long"
},
"wk": {
"short": "midgard5.actor-wk",
"long": "midgard5.actor-wk-long"
}
},
"fw": 8,
"attribute": "st",
"skill": "",
"type": "general",
"rolls": {
"formulas": {
"0": {
"formula": "1d20 + @i.fw + @i.calc.bonus",
"enabled": true,
"label": "EW"
}
},
"output": ""
},
"calc": {}
},
"effects": [],
"folder": null,
"sort": 0,
"permission": {
"default": 0,
"XD0IpWT6bN4AJiYQ": 3
},
"_id": "4N0IgVDj1eee0hSB"
}

View File

@ -1,69 +0,0 @@
{
"name": "Angeborene Fähigkeit",
"type": "skill",
"img": "icons/svg/item-bag.svg",
"data": {
"description": "",
"attributes": {
"st": {
"short": "midgard5.actor-st",
"long": "midgard5.actor-st-long"
},
"gs": {
"short": "midgard5.actor-gs",
"long": "midgard5.actor-gs-long"
},
"gw": {
"short": "midgard5.actor-gw",
"long": "midgard5.actor-gw-long"
},
"ko": {
"short": "midgard5.actor-ko",
"long": "midgard5.actor-ko-long"
},
"in": {
"short": "midgard5.actor-in",
"long": "midgard5.actor-in-long"
},
"zt": {
"short": "midgard5.actor-zt",
"long": "midgard5.actor-zt-long"
},
"au": {
"short": "midgard5.actor-au",
"long": "midgard5.actor-au-long"
},
"pa": {
"short": "midgard5.actor-pa",
"long": "midgard5.actor-pa-long"
},
"wk": {
"short": "midgard5.actor-wk",
"long": "midgard5.actor-wk-long"
}
},
"fw": 6,
"attribute": "",
"skill": "",
"type": "innate",
"rolls": {
"formulas": {
"0": {
"formula": "1d20 + @i.fw + @i.calc.bonus",
"type": "ew",
"label": "EW"
}
},
"output": ""
},
"calc": {}
},
"effects": [],
"folder": null,
"sort": 0,
"permission": {
"default": 0,
"XD0IpWT6bN4AJiYQ": 3
},
"_id": "nkMkMFNDSdvlP1Jt"
}

View File

@ -1,39 +0,0 @@
{
"name": "Gegenstand",
"type": "item",
"img": "icons/svg/item-bag.svg",
"system": {
"description": "",
"equippable": false,
"equipped": true,
"value": 0,
"magic": false,
"rolls": {
"formulas": {},
"output": ""
},
"mods": {},
"calc": {}
},
"effects": [],
"flags": {
"core": {
"sourceId": "Item.8GrWgO1jjysZPnxc"
}
},
"_stats": {
"systemId": "midgard5",
"systemVersion": "1.1.0",
"coreVersion": "10.291",
"createdTime": 1681862229001,
"modifiedTime": 1681862253981,
"lastModifiedBy": "Fphp3NQlJ6KWctyq"
},
"folder": null,
"sort": 0,
"ownership": {
"default": 0,
"Fphp3NQlJ6KWctyq": 3
},
"_id": "ERcxMh7hWiv42rfx"
}

View File

@ -1,46 +0,0 @@
{
"name": "Rüstung",
"type": "armor",
"img": "icons/svg/item-bag.svg",
"data": {
"description": "",
"stats": {
"damageBonus": 0,
"attackBonus": 0,
"defenseBonus": 0,
"movementBonus": 0,
"resistanceMind": 0,
"resistanceBody": 0,
"spellBonus": 0
},
"equippable": false,
"equipped": true,
"attributeMod": {
"st": 0,
"gs": 0,
"gw": 0,
"ko": 0,
"in": 0,
"zt": 0,
"au": 0,
"pa": 0,
"wk": 0
},
"magic": false,
"lpProtection": 0,
"apProtection": 0,
"rolls": {
"formulas": {},
"output": ""
},
"calc": {}
},
"effects": [],
"folder": null,
"sort": 0,
"permission": {
"default": 0,
"XD0IpWT6bN4AJiYQ": 3
},
"_id": "pV1hNavlQGJ9UaEf"
}

View File

@ -1,69 +0,0 @@
{
"name": "Sprache",
"type": "skill",
"img": "icons/svg/item-bag.svg",
"data": {
"description": "",
"attributes": {
"st": {
"short": "midgard5.actor-st",
"long": "midgard5.actor-st-long"
},
"gs": {
"short": "midgard5.actor-gs",
"long": "midgard5.actor-gs-long"
},
"gw": {
"short": "midgard5.actor-gw",
"long": "midgard5.actor-gw-long"
},
"ko": {
"short": "midgard5.actor-ko",
"long": "midgard5.actor-ko-long"
},
"in": {
"short": "midgard5.actor-in",
"long": "midgard5.actor-in-long"
},
"zt": {
"short": "midgard5.actor-zt",
"long": "midgard5.actor-zt-long"
},
"au": {
"short": "midgard5.actor-au",
"long": "midgard5.actor-au-long"
},
"pa": {
"short": "midgard5.actor-pa",
"long": "midgard5.actor-pa-long"
},
"wk": {
"short": "midgard5.actor-wk",
"long": "midgard5.actor-wk-long"
}
},
"fw": 8,
"attribute": "in",
"skill": "",
"type": "language",
"rolls": {
"formulas": {
"0": {
"formula": "1d20 + @i.calc.fw + @i.calc.bonus",
"enabled": true,
"label": "EW"
}
},
"output": ""
},
"calc": {}
},
"effects": [],
"folder": null,
"sort": 0,
"permission": {
"default": 0,
"XD0IpWT6bN4AJiYQ": 3
},
"_id": "rDN14z3lNJISWTdO"
}

View File

@ -1,42 +0,0 @@
{
"name": "Verteidigungswaffe",
"type": "defensiveWeapon",
"img": "icons/svg/item-bag.svg",
"data": {
"description": "",
"stats": {
"damageBonus": 0,
"attackBonus": 0,
"defenseBonus": 0,
"movementBonus": 0,
"resistanceMind": 0,
"resistanceBody": 0,
"spellBonus": 0
},
"equippable": false,
"equipped": true,
"special": false,
"magic": false,
"skillId": "",
"rolls": {
"formulas": {
"0": {
"formula": "1d20 + @i.calc.fw + @i.calc.bonus + @i.calc.special + @c.calc.stats.defense.value + @c.calc.stats.defenseBonus.value + @i.stats.defenseBonus",
"enabled": true,
"label": "Abwehr"
}
},
"output": ""
},
"calc": {},
"damageBase": ""
},
"effects": [],
"folder": null,
"sort": 0,
"permission": {
"default": 0,
"XD0IpWT6bN4AJiYQ": 3
},
"_id": "BNAoHN0vHfcwNUTl"
}

View File

@ -1,48 +0,0 @@
{
"name": "Waffe",
"type": "weapon",
"img": "icons/svg/item-bag.svg",
"data": {
"description": "",
"stats": {
"damageBonus": 0,
"attackBonus": 0,
"defenseBonus": 0,
"movementBonus": 0,
"resistanceMind": 0,
"resistanceBody": 0,
"spellBonus": 0
},
"equippable": false,
"equipped": true,
"special": false,
"magic": false,
"ranged": false,
"skillId": "",
"damageBase": "1d6",
"rolls": {
"formulas": {
"0": {
"formula": "1d20 + @i.calc.fw + @i.calc.bonus + @i.calc.special + @c.calc.stats.attackBonus.value + @i.stats.attackBonus",
"enabled": true,
"label": "Angriff"
},
"1": {
"formula": "@i.damageBase + @i.stats.damageBonus + @c.calc.stats.damageBonus.value",
"enabled": true,
"label": "Schaden"
}
},
"output": ""
},
"calc": {}
},
"effects": [],
"folder": null,
"sort": 0,
"permission": {
"default": 0,
"XD0IpWT6bN4AJiYQ": 3
},
"_id": "uGQJ4VPhh135e79a"
}

View File

@ -1,69 +0,0 @@
{
"name": "Waffenfertigkeit",
"type": "skill",
"img": "icons/svg/item-bag.svg",
"data": {
"description": "",
"attributes": {
"st": {
"short": "midgard5.actor-st",
"long": "midgard5.actor-st-long"
},
"gs": {
"short": "midgard5.actor-gs",
"long": "midgard5.actor-gs-long"
},
"gw": {
"short": "midgard5.actor-gw",
"long": "midgard5.actor-gw-long"
},
"ko": {
"short": "midgard5.actor-ko",
"long": "midgard5.actor-ko-long"
},
"in": {
"short": "midgard5.actor-in",
"long": "midgard5.actor-in-long"
},
"zt": {
"short": "midgard5.actor-zt",
"long": "midgard5.actor-zt-long"
},
"au": {
"short": "midgard5.actor-au",
"long": "midgard5.actor-au-long"
},
"pa": {
"short": "midgard5.actor-pa",
"long": "midgard5.actor-pa-long"
},
"wk": {
"short": "midgard5.actor-wk",
"long": "midgard5.actor-wk-long"
}
},
"fw": 5,
"attribute": "",
"skill": "",
"type": "combat",
"rolls": {
"formulas": {
"0": {
"formula": "1d20 + @i.calc.fw + @i.calc.bonus",
"enabled": true,
"label": "EW"
}
},
"output": ""
},
"calc": {}
},
"effects": [],
"folder": null,
"sort": 0,
"permission": {
"default": 0,
"XD0IpWT6bN4AJiYQ": 3
},
"_id": "1E4XHTGZlned2ofY"
}

View File

@ -1,67 +0,0 @@
{
"name": "Zauber",
"type": "spell",
"img": "icons/svg/item-bag.svg",
"data": {
"description": "",
"spellProcessSelection": {
"none": "midgard5.spell-process-none",
"beherrschen": "midgard5.spell-process-beherrschen",
"bewegen": "midgard5.spell-process-bewegen",
"erkennen": "midgard5.spell-process-erkennen",
"erschaffen": "midgard5.spell-process-erschaffen",
"formen": "midgard5.spell-process-formen",
"veraendern": "midgard5.spell-process-veraendern",
"zerstoeren": "midgard5.spell-process-zerstoeren",
"wundertat": "midgard5.spell-process-wundertat",
"dweomer": "midgard5.spell-process-dweomer",
"zauberlied": "midgard5.spell-process-zauberlied",
"salz": "midgard5.spell-process-salz",
"thaumagraphie": "midgard5.spell-process-thaumagraphie",
"beschwoeren": "midgard5.spell-process-beschwoeren",
"nekromantie": "midgard5.spell-process-nekromantie",
"thaumatherapie": "midgard5.spell-process-thaumatherapie",
"zaubermittel": "midgard5.spell-process-zaubermittel",
"zauberschutz": "midgard5.spell-process-zauberschutz"
},
"spellTypeSelection": {
"gedanke": "midgard5.spell-type-gedanke",
"geste": "midgard5.spell-type-geste",
"wort": "midgard5.spell-type-wort"
},
"spellTargetSelection": {
"umgebung": "midgard5.spell-target-umgebung",
"geist": "midgard5.spell-target-geist",
"koerper": "midgard5.spell-target-koerper"
},
"bonus": 0,
"type": "gedanke",
"process": "none",
"ap": 0,
"castDuration": "",
"range": "",
"effectTarget": "umgebung",
"effectArea": "",
"effectDuration": "",
"origin": "",
"rolls": {
"formulas": {
"0": {
"formula": "1d20 + @c.calc.stats.spellCasting.value + @i.bonus",
"enabled": true,
"label": "Zaubern"
}
},
"output": ""
},
"calc": {}
},
"effects": [],
"folder": null,
"sort": 0,
"permission": {
"default": 0,
"XD0IpWT6bN4AJiYQ": 3
},
"_id": "HQ469FvZkwKfzFfu"
}

View File

@ -1,19 +0,0 @@
{
"name": "Kritische Fehler beim Zaubern",
"permission": {
"default": 2,
"CBq5YXAqbO7HoJ03": 3
},
"type": "script",
"flags": {
"core": {
"sourceId": "Macro.e4KLlTBq8Z4Pt7In"
}
},
"scope": "global",
"command": "await game.tables.getName(\"Kritische Fehler beim Zaubern\").draw()",
"author": "CBq5YXAqbO7HoJ03",
"img": "systems/midgard5/assets/icons/macro/kritfehlerzauber.svg",
"actorIds": [],
"_id": "XtzGuyYRyX8wVi1e"
}

View File

@ -1,19 +0,0 @@
{
"name": "Kritischer Erfolg bei der Abwehr",
"permission": {
"default": 2,
"CBq5YXAqbO7HoJ03": 3
},
"type": "script",
"flags": {
"core": {
"sourceId": "Macro.P6jQGko7PdG6Xlhe"
}
},
"scope": "global",
"command": "await game.tables.getName(\"Kritische Erfolg bei der Abwehr\").draw()",
"author": "CBq5YXAqbO7HoJ03",
"img": "systems/midgard5/assets/icons/macro/kriterfolgabwehr.svg",
"actorIds": [],
"_id": "qWyrwvh7g9CbTKg9"
}

View File

@ -1,19 +0,0 @@
{
"name": "Kritischer Fehler bei Angriffen",
"permission": {
"default": 2,
"CBq5YXAqbO7HoJ03": 3
},
"type": "script",
"flags": {
"core": {
"sourceId": "Macro.FZUermrYHSbrEluS"
}
},
"scope": "global",
"command": "await game.tables.getName(\"Kritische Fehler bei Angriffen\").draw()",
"author": "CBq5YXAqbO7HoJ03",
"img": "systems/midgard5/assets/icons/macro/kritfehlerangriff.svg",
"actorIds": [],
"_id": "798kmgnTkpfP89Z9"
}

View File

@ -1,19 +0,0 @@
{
"name": "Kritischer Fehler bei der Abwehr",
"permission": {
"default": 2,
"CBq5YXAqbO7HoJ03": 3
},
"type": "script",
"flags": {
"core": {
"sourceId": "Macro.k1tLp8Q2NY9twiZ6"
}
},
"scope": "global",
"command": "await game.tables.getName(\"Kritische Fehler bei der Abwehr\").draw()",
"author": "CBq5YXAqbO7HoJ03",
"img": "systems/midgard5/assets/icons/macro/kritfehlerabwehr.svg",
"actorIds": [],
"_id": "W7rYb00B6rtabV05"
}

View File

@ -1,19 +0,0 @@
{
"name": "Kritischer Schaden",
"permission": {
"default": 2,
"CBq5YXAqbO7HoJ03": 3
},
"type": "script",
"flags": {
"core": {
"sourceId": "Macro.QZlbT0tgD2aYW5YJ"
}
},
"scope": "global",
"command": "await game.tables.getName(\"Kritischer Schaden\").draw()",
"author": "CBq5YXAqbO7HoJ03",
"img": "systems/midgard5/assets/icons/macro/kriterfolgangriff.svg",
"actorIds": [],
"_id": "48DUqxdpHDCGKOHp"
}

View File

@ -1,19 +0,0 @@
{
"name": "1W10",
"permission": {
"default": 2,
"CBq5YXAqbO7HoJ03": 3
},
"type": "chat",
"flags": {
"core": {
"sourceId": "Macro.TqmUKpMpY4GhiTML"
}
},
"scope": "global",
"command": "/r 1d10",
"author": "CBq5YXAqbO7HoJ03",
"img": "systems/midgard5/assets/icons/wurfel/w10.svg",
"actorIds": [],
"_id": "YWsPRUpZpgLBKIB3"
}

View File

@ -1,19 +0,0 @@
{
"name": "1W100",
"permission": {
"default": 2,
"CBq5YXAqbO7HoJ03": 3
},
"type": "chat",
"flags": {
"core": {
"sourceId": "Macro.S01PfXnvLPeuKOH8"
}
},
"scope": "global",
"command": "/r 1d100",
"author": "CBq5YXAqbO7HoJ03",
"img": "systems/midgard5/assets/icons/wurfel/w100.svg",
"actorIds": [],
"_id": "pXZIfqDIX9VKYonr"
}

View File

@ -1,19 +0,0 @@
{
"name": "1W20",
"permission": {
"default": 2,
"CBq5YXAqbO7HoJ03": 3
},
"type": "chat",
"flags": {
"core": {
"sourceId": "Macro.mj9nIEgk0UDz8tbH"
}
},
"scope": "global",
"command": "/r 1d20",
"author": "CBq5YXAqbO7HoJ03",
"img": "systems/midgard5/assets/icons/wurfel/w20.svg",
"actorIds": [],
"_id": "qBoxslCQXxR22xKc"
}

View File

@ -1,19 +0,0 @@
{
"name": "1W6",
"permission": {
"default": 2,
"CBq5YXAqbO7HoJ03": 3
},
"type": "chat",
"flags": {
"core": {
"sourceId": "Macro.QBhV6De80g1wH6ot"
}
},
"scope": "global",
"command": "/r 1d6",
"author": "CBq5YXAqbO7HoJ03",
"img": "systems/midgard5/assets/icons/wurfel/w6.svg",
"actorIds": [],
"_id": "5tpfRgbM5sTL9gur"
}

View File

@ -1,163 +0,0 @@
{
"name": "Kritische Fehler beim Zaubern",
"permission": {
"default": 2,
"CBq5YXAqbO7HoJ03": 3
},
"flags": {
"exportSource": {
"world": "midgard-test",
"system": "midgard5",
"coreVersion": "0.7.9",
"systemVersion": 0.02
}
},
"img": "icons/svg/book.svg",
"description": "<h2>Tabelle 1: Kritische Fehler Beim Zaubern</h2><h3><b>*</b>: Die Magie wirkt auf ein falsches Ziel oder hat einen unerwünschten Effekt. Werden dabei Wesen betroffen, die nicht verzaubert werden wollen, steht ihnen ein WW:Resistenz oder ein WW:Abwehr zu. Dabei zählt allerdings nicht das Würfelergebnis von 1, das zu dem kritischen Fehler geführt hat, sondern der ungeschickte Zauberer wiederholt in diesen Fällen den EW:Zaubern. Diesem neuen Gesamtergebnis müssen die Opfer \ndes kritischen Fehlers widerstehen, um der magischen Wirkung \nzu entgehen - auch wenn es unter 20 liegt. Fällt bei diesem wiederholten EW:Zaubern eine 1 oder eine 20, so hat dies keine besonderen Folgen.</br>Wird ein kritischer Fehler erwürfelt, der für einen Spruch sinnlos ist, wird stattdessen der Zauberer geschwächt. Er kann [[1d6]] Runden nicht zaubern.</h3>",
"results": [
{
"_id": "LW9UnEaonREGKzTy",
"flags": {},
"type": 0,
"text": "Keine besonderen Auswirkungen.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 10,
"range": [
1,
10
],
"drawn": false
},
{
"_id": "G7GgXxFcsfsbUcwi",
"flags": {},
"type": 0,
"text": "<h3><b>*</b> Der Zauberer verspricht sich oder kann seine Gedanken nicht zusammenhalten.</h3>Es kommt zu einer Entladung magischer Energie, die wirkungslos verpufft, dem Zauberer aber einen leichten thaumatischen Schock versetzt. Er kann [[1d6]] Runden (*10 sec) lang nicht zaubern.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 20,
"range": [
11,
30
],
"drawn": false
},
{
"_id": "7vVkIs4duqhpJaKq",
"flags": {},
"type": 0,
"text": "<h3>Der Zauberer unterschätzt das Ausmaß des Flusses arkaner Energie.</h3>Der Zauberer setzt mehr Magan in Bewegung als nötig. Der Überfluss entzieht sich seiner Kontrolle und breitet sich schlagartig in seinem Astralleib aus. Diese Störung lässt den Spruch fehlschlagen. Der Zauberer verliert dadurch doppelt so viele AP wie üblich.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 20,
"range": [
31,
50
],
"drawn": false
},
{
"_id": "S5d86WFP7bCmatNp",
"flags": {},
"type": 0,
"text": "<h3><b>*</b> Der Zauberer irrt sich bei der Festlegung des Effekts.</h3>Das Opfer wird gestärkt statt geschwächt, verwundet statt geheilt, es wird wärmer statt kühler usw. Soweit möglich, geschieht das Gegenteil dessen, was der Zauberer erreichen wollte.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 10,
"range": [
51,
60
],
"drawn": false
},
{
"_id": "I3XXLhTRCdE19Vmd",
"flags": {},
"type": 0,
"text": "<h3><b>*</b> Der Zauberer irrt sich bei der Auswahl des Opfers/ des Wirkungsbereichs.</h3>Der Spruch wirkt auf ein zufällig bestimmtes Wesen oder Objekt innerhalb der Reichweite. Bei räumlichen Wirkungsbereichen breitet sich die Magie in die genau entgegengesetzte Richtung (Kegel oder Strahl) aus bzw. liegt das Zentrum der Wirkung in entgegengesetzter Richtung vom Zauberer aus gesehen (Umkreis).",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 10,
"range": [
61,
70
],
"drawn": false
},
{
"_id": "ciB0pGZyV4KjV5iO",
"flags": {},
"type": 0,
"text": "<h3>Der Zauberer wird geschwächt.</h3>Der Spruch misslingt, aber die bereits freigesetzte Energie schwächt Körper und Geist des Zauberers. Er verliert [[1d6]] AP und kann [[1d6*10]] min lang nicht zaubern.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 10,
"range": [
71,
80
],
"drawn": false
},
{
"_id": "xx6BVgf3NbpFJLaQ",
"flags": {},
"type": 0,
"text": "<h3>Es kommt zu einer magischen Stauung.</h3>Die falsche Ausführung des Zaubers verhindert die Weiterleitung der erzeugten arkanen Energie. Die starke Ansammlung von Magan im Argyriston des Zauberers zieht dieses in Mitleidenschaft. Sein Zaubertalent sinkt für [[1d6]] Tage auf die Hälfte des normalen Wertes - mit entsprechenden Folgen für seinen persönlichen Zauberbonus. Dieser negative Effekt kann mit Allheilung vorzeitig aufgehoben werden.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 10,
"range": [
81,
90
],
"drawn": false
},
{
"_id": "Q3QjCiHYzLVtrXz3",
"flags": {},
"type": 0,
"text": "<h3>Der Zauberer erleidet eine schwere Bewusstseinsstörung.</h3>Die Entladung magischer Energie beim Scheitern des Spruches versetzt dem Zauberer einen schweren thaumatischen Schock. Er verliert dadurch [[1d6]] LP und AP und kann in der nächsten Stunde nicht zaubern. Übersteigen die LP-Verluste ein Drittel des LP Maximums, so fällt der Zauberer in ein Koma, aus dem er nach [[1d6]] Tagen erwacht. Mit Allheilung kann er vorher aufgeweckt werden.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 5,
"range": [
91,
95
],
"drawn": false
},
{
"_id": "QICP7DgbyTmp1Nns",
"flags": {},
"type": 0,
"text": "<h3><b>*</b>Der Zauberer verzaubert sich selbst.</h3>Bei einem Geistes- oder Körperzauber trifft die volle Wirkung der Magie den Zauberer selbst, wenn ihm ein WW:Resistenz misslingt. Schützende Zauber funktionieren also gegebenenfalls ganz normal (Glück im Unglück). Kontrollzauber wie Macht über Menschen führen zur vorübergehenden Handlungsunfähigkeit des Zauberers; sein Geist versucht, die Kontrolle über sich selbst zu übernehmen, so dass er völlig mit sich selbst beschäftigt ist, bis ihm ein alle 2 min erlaubter EW:Resistenz gelingt. Sprü- che, die wie Macht über die belebte Natur nur auf Tiere wirken, haben keinen Effekt. Bei Umgebungszaubern tritt stattdessen der unter 91-95 beschriebene Effekt ein.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 4,
"range": [
96,
99
],
"drawn": false
},
{
"_id": "qY2J5MqMZvNzspnt",
"flags": {},
"type": 0,
"text": "<h3>Zauberwerk wird in Mitleidenschaft gezogen.</h3>Der Spruch misslingt; die dabei freigesetzte Energie stört die Magie von Zauberwerk, das der Zauberer mit sich führt. Jeder magische Gegenstand in bis zu 1 m Entfernung ist mit einer Chance von 10%+Stufe des misslungenen Zaubers betroffen: Zaubermittel (Trünke, Kräuter usw.) verlieren ihre Eigenschaften, Amulette werden wirkungslos, Spruchrollen leeren sich. Bei verzauberten Waffen oder Rüstungen gehen [[1d63]] von allen magischen Zuschlägen verloren. Bei Artefakten mit mehreren Wirkungen wird für jede einzeln gewürfelt, ob sie betroffen ist.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 1,
"range": [
100,
100
],
"drawn": false
}
],
"formula": "1d100",
"replacement": true,
"displayRoll": true,
"_id": "PRovcPRqdrvFRpFN"
}

View File

@ -1,142 +0,0 @@
{
"name": "Kritischer Erfolg bei der Abwehr",
"permission": {
"default": 2,
"CBq5YXAqbO7HoJ03": 3
},
"flags": {},
"img": "icons/svg/holy-shield.svg",
"description": "<h2>Tabelle 6: Kritischer Erfolg bei der Abwehr</h2>",
"results": [
{
"_id": "ImLGlzC3AuyT5VMl",
"flags": {},
"type": 0,
"text": "Keine besonderen Auswirkungen.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 10,
"range": [
1,
10
],
"drawn": false
},
{
"_id": "PPQUPOo5JGRkKPXQ",
"flags": {},
"type": 0,
"text": "Die Waffenhand des Angreifers wird geprellt. In der folgenden Runde kann er mit dieser Hand nicht angreifen. Tiere verlieren einen Angriff mit Pranke, Zähnen, Stachel usw.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 20,
"range": [
11,
30
],
"drawn": false
},
{
"_id": "IpRVlty1p1it0eMm",
"flags": {},
"type": 0,
"text": "Der Angreifer wird entwaffnet. Die Waffe fliegt vom Angreifer aus gesehen geradlinig um [[1d61]] m nach links. Bei waffenlosen Angriffen gibt es keine besonderen Auswirkungen.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 10,
"range": [
31,
40
],
"drawn": false
},
{
"_id": "fh01DVN6rFKrTdcg",
"flags": {},
"type": 0,
"text": "Der Angreifer wird entwaffnet. Die Waffe fliegt nach rechts (s. 31-40).",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 10,
"range": [
41,
50
],
"drawn": false
},
{
"_id": "k1rD7t7YnayTcV9P",
"flags": {},
"type": 0,
"text": "Der Angreifer wird entwaffnet. Die Waffe fliegt nach hinten (s. 31-40).",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 10,
"range": [
51,
60
],
"drawn": false
},
{
"_id": "9WFBq8PAy1fFxe4I",
"flags": {},
"type": 0,
"text": "Der Angreifer stürzt zu Boden. Er ist vom Abwehrenden umgestoßen worden oder gestolpert. In einem Handgemenge treten keine besonderen Folgen auf.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 20,
"range": [
61,
80
],
"drawn": false
},
{
"_id": "u5kKsW1vnvWvF79s",
"flags": {},
"type": 0,
"text": "Der Angreifer wird leicht verwundet. Er verliert [[1d6]] AP.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 15,
"range": [
81,
95
],
"drawn": false
},
{
"_id": "gTvVtavg5GElh0pg",
"flags": {},
"type": 0,
"text": "Der Angreifer wird schwer verwundet. Er erleidet [[1d6]] schweren Schaden.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 4,
"range": [
96,
99
],
"drawn": false
},
{
"_id": "507Nvm6dWIlN8Ip1",
"flags": {},
"type": 0,
"text": "Der Angreifer verliert das Bewusstsein. Er stürzt zu Boden und kommt erst [[1d6]] Runden später wieder zu sich.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 1,
"range": [
100,
100
],
"drawn": false
}
],
"formula": "1d100",
"replacement": true,
"displayRoll": true,
"_id": "JOQf46Cj29MwcKsY"
}

View File

@ -1,163 +0,0 @@
{
"name": "Kritischer Fehler bei Angriffen",
"permission": {
"default": 2,
"CBq5YXAqbO7HoJ03": 3
},
"flags": {
"exportSource": {
"world": "midgard-test",
"system": "midgard5",
"coreVersion": "0.7.9",
"systemVersion": 0.02
}
},
"img": "icons/svg/d20-grey.svg",
"description": "<h2>Tabelle 4: Kritische Fehler bei Angriffen</h2>",
"results": [
{
"_id": "dIX62PrnwNTY929l",
"flags": {},
"type": 0,
"text": "<h3>Keine besonderen Auswirkungen.</h3>",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 10,
"range": [
1,
10
],
"drawn": false
},
{
"_id": "IgEkc7L4KlW745gH",
"flags": {},
"type": 0,
"text": "<h3>Der Angreifer verliert kurz das Gleichgewicht.</h3>Er braucht etwas Zeit, um wieder kampfbereit zu sein, und kann in der folgenden Runde nicht angreifen.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 10,
"range": [
11,
20
],
"drawn": false
},
{
"_id": "lXeIddddllhBc5aj",
"flags": {},
"type": 0,
"text": "<h3>Der Angreifer lässt seine Waffe fallen.</h3>Sie fällt auf das Feld, auf dem er sich befi ndet. Fäuste, Pranken usw. werden leicht geprellt und können in der folgenden Runde nicht eingesetzt werden.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 15,
"range": [
21,
35
],
"drawn": false
},
{
"_id": "hNjE2KIIGCvgcBjf",
"flags": {},
"type": 0,
"text": "<h3>Die Angriffswaffe wird zerstört.</h3>Bei magischen Waffen wird 1W61 ([[1d6-1]])gewürfelt; die Waffe wird nur zerstört, wenn das Ergebnis über dem höheren der beiden magischen Bonuswerte für Angriff und Schaden liegt. Bei Angriffen mit Fäusten, Zähnen usw. wird der betreffende Körperteil geprellt und kann 10 min lang nicht eingesetzt werden.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 15,
"range": [
36,
50
],
"drawn": false
},
{
"_id": "2mW1vM6xy0emVwDM",
"flags": {},
"type": 0,
"text": "<h3>Der Angreifer verletzt sich selbst.</h3>Im Nahkampf und Handgemenge mit einer Waffe erleidet er durch seine Ungeschicklichkeit [[1d61]] schweren Schaden. Bei Angriffen mit der bloßen Hand und anderen natürlichen Waffen oder mit Wurfwaffen verliert der Angreifer [[1d61]] AP durch eine Muskel zerrung und kann eine Runde lang nicht angreifen. Bei einem Bogen- oder Armbrustschuss reißt die Sehne und verletzt den Schützen leicht ([[1d61]] AP Verlust). Sie kann in [[1d6+3]] Runden durch eine neue ersetzt werden.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 5,
"range": [
51,
55
],
"drawn": false
},
{
"_id": "bd5AxyNFZ2RQ7Aq0",
"flags": {},
"type": 0,
"text": "<h3>Der Angreifer trifft aus Versehen die nächststehende befreundete Person.</h3>Er fügt ihr [[1d61]] schweren Schaden zu. Befi ndet sich kein Gefährte in Reichweite, hat der Fehler keine Folgen. Kommen mehrere Personen als Opfer in Frage, wird eine von ihnen ausgewürfelt.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 5,
"range": [
56,
60
],
"drawn": false
},
{
"_id": "CY9a5ajPDQGns8CN",
"flags": {},
"type": 0,
"text": "<h3>Der Angreifer läuft in die Waffe des Gegners hinein.</h3>Der Angegriffene darf sofort außer der Reihe einen zusätzlichen EW:Angriff machen, der nicht abgewehrt werden darf.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 10,
"range": [
61,
70
],
"drawn": false
},
{
"_id": "pVHTa2JuXutMDar7",
"flags": {},
"type": 0,
"text": "<h3>Der Angreifer verstaucht sich den Fuß.</h3>Seine Bewegungsweite verringert sich für [[2d6]] Runden um ein Drittel. Bei einem Schuss mit Bogen oder Armbrust schlägt die Sehne gegen den Arm des Abenteurers, der dadurch [[1d61]] AP verliert und eine Runde lang nicht schießen kann.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 20,
"range": [
71,
90
],
"drawn": false
},
{
"_id": "q4hhhMPXWJlmFMY7",
"flags": {},
"type": 0,
"text": "<h3>Der Angreifer stolpert und stürzt zu Boden.</h3>Bei Armbrust- oder Bogenschuss reißt stattdessen die Sehne und verletzt den Schützen leicht [[1d61]] AP Verlust - s. 51-55). Im Handgemenge hat dieser Wurf dieselben Folgen wie 71-90.<p>51-55</p><p>Der Angreifer trifft aus Versehen die nächststehende befreundete Person. Er fügt ihr [[1d61]] schweren Schaden zu. Befi ndet sich kein Gefährte in Reichweite, hat der Fehler keine Folgen. Kommen mehrere Personen als Opfer in Frage, wird eine von ihnen ausgewürfelt. </p><p>71-90</p><p>Der Angreifer verstaucht sich den Fuß.Seine Bewegungsweite verringert sich für [[2d6]] Runden um ein Drittel. Bei einem Schuss mit Bogen oder Armbrust schlägt die Sehne gegen den Arm des Abenteurers, der dadurch [[1d61]] AP verliert und eine Runde lang nicht schießen kann.</p>",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 9,
"range": [
91,
99
],
"drawn": false
},
{
"_id": "huSeP6mv8OeNYJDj",
"flags": {},
"type": 0,
"text": "<h3>Der Angreifer stürzt zu Boden und zerstört dabei seine Waffe</h3>. Bei einem Angriff mit natürlichen Waffen kann der betreffende Körperteil wie bei 36-50 10 min lang nicht eingesetzt werden. Bei einem Angriff mit Schusswaffen fällt der Abenteurer nicht hin.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 1,
"range": [
100,
100
],
"drawn": false
}
],
"formula": "1d100",
"replacement": true,
"displayRoll": true,
"_id": "sVgHbAxseIoeIMz8"
}

View File

@ -1,177 +0,0 @@
{
"name": "Kritischer Fehler bei der Abwehr",
"permission": {
"default": 2,
"CBq5YXAqbO7HoJ03": 3
},
"flags": {
"exportSource": {
"world": "midgard-test",
"system": "midgard5",
"coreVersion": "0.7.9",
"systemVersion": 0.02
}
},
"img": "icons/svg/fire-shield.svg",
"description": "<h2>Tabelle 5: Kritischer Fehler bei der Abwehr</h2>",
"results": [
{
"_id": "Xdzk7cvwwnI2i18M",
"flags": {},
"type": 0,
"text": "<h3>Keine besonderen Auswirkungen.</h3>",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 10,
"range": [
1,
10
],
"drawn": false
},
{
"_id": "8xuz2YsB90Z0KbLs",
"flags": {},
"type": 0,
"text": "<h3>Der Angegriffene verliert kurz das Gleichgewicht.</h3>Er braucht etwas Zeit, um wieder kampfbereit zu sein, und kann in der folgenden Runde nicht angreifen.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 10,
"range": [
11,
20
],
"drawn": false
},
{
"_id": "gpzhwQyLX429zUz0",
"flags": {},
"type": 0,
"text": "<h3>Die Verteidigungswaffe ist zerstört.</h3>Benutzt der Abenteurer weder Schild noch Parierwaffe, hat dieser Wurf dieselben Folgen wie 81 - 90. Bei magischen Waffen wird 1W61 ([[1d6-1]]) gewürfelt; die Waffe wird nur zerstört, wenn das Ergebnis größer als ihr magischer Abwehrbonus ist.<p>81-90</p>Der Verteidiger prallt unglücklich mit seinem Gegner zusammen (Nahkampf und Handgemenge) oder gegen ein Hindernis (Fernkampf) und ist kurzzeitig benommen. Im Nahkampf oder Handgemenge kann er in der folgenden Runde weder angreifen noch abwehren. Sein Gegner leidet unter denselben Folgen - aber nur, wenn ihm ein PW:Gewandtheit misslingt. Im Fernkampf kann der Angegriffene wie bei 61-70 dem nächsten Schuss nicht ausweichen und darf außerdem in dieser und der folgenden Runde nicht mehr angreifen.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 10,
"range": [
21,
30
],
"drawn": false
},
{
"_id": "Znrv6r6SHSBEclYd",
"flags": {},
"type": 0,
"text": "<h3>Der Angegriffene lässt seine Verteidigungswaffe fallen.</h3>Die Waffe fällt ihm zu Füßen. Benutzt er weder Schild noch Parierwaffe, hat dieser Wurf dieselben Folgen wie 41-50.<p>41-50</p>Der Verteidiger wird nach hinten gedrängt (Nahkampf), oder der Schwung seiner Ausweichbewegung reißt ihn mit (Fernkampf). Im Nahkampf bewegt sich der Angegriffene 1 m geradlinig vom Gegner weg, wenn ihn kein massives Hindernis daran hindert - selbst wenn er dadurch in ein Lagerfeuer oder einen Abgrund hineingerät. Der Angreifer kann sofort folgen und den Kontakt aufrechterhalten, wenn er will. Im Fernkampf bewegt sich der Angegriffene von seinem Standort aus um 1 m nach links (bei 1-2 mit [[1d6]]), nach rechts (bei 3-4), nach vorne (5) bzw. nach hinten (6), wenn ihn kein Hindernis daran hindert. Im Handgemenge hat der Wurf dieselben Folgen wie 51-60.<p>51-60</p>Die Sicht des Angegriffenen wird behindert. Er kann in der folgenden Runde nicht angreifen, da er Blut oder Schweiß aus den Augen wischen oder eine verrutschte Kopfbedeckung zurechtrücken muss.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 10,
"range": [
31,
40
],
"drawn": false
},
{
"_id": "wLeOWz8B21WCkEwK",
"flags": {},
"type": 0,
"text": "<h3>Der Verteidiger wird nach hinten gedrängt (Nahkampf), oder der Schwung seiner Ausweichbewegung reißt ihn mit (Fernkampf).</h3>Im Nahkampf bewegt sich der Angegriffene 1 m geradlinig vom Gegner weg, wenn ihn kein massives Hindernis daran hindert - selbst wenn er dadurch in ein Lagerfeuer oder einen Abgrund hineingerät. Der Angreifer kann sofort folgen und den Kontakt aufrechterhalten, wenn er will. Im Fernkampf bewegt sich der Angegriffene von seinem Standort aus um 1 m nach links (bei 1-2 mit [[1d6]]), nach rechts (bei 3-4), nach vorne (5) bzw. nach hinten (6), wenn ihn kein Hindernis daran hindert. Im Handgemenge hat der Wurf dieselben Folgen wie 51-60.<p>51-60</p>Die Sicht des Angegriffenen wird behindert. Er kann in der folgenden Runde nicht angreifen, da er Blut oder Schweiß aus den Augen wischen oder eine verrutschte Kopfbedeckung zurechtrücken muss.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 10,
"range": [
41,
50
],
"drawn": false
},
{
"_id": "OK1TzYWgPDqvBF6K",
"flags": {},
"type": 0,
"text": "<h3>Die Sicht des Angegriffenen wird behindert.</h3>Er kann in der folgenden Runde nicht angreifen, da er Blut oder Schweiß aus den Augen wischen oder eine verrutschte Kopfbedeckung zurechtrücken muss.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 10,
"range": [
51,
60
],
"drawn": false
},
{
"_id": "jmWy6vH4NYiGghPE",
"flags": {},
"type": 0,
"text": "<h3>Der Verteidiger gibt sich eine Blöße.</h3>Im Nahkampf oder Handgemenge darf der Angreifer sofort außer der Reihe einen zusätzlichen EW:Angriff machen, der nicht abgewehrt werden darf. Im Fernkampf kann der Angegriffene dem nächsten Schuss oder Wurf (in der laufenden oder folgenden Runde, nicht aber später) nicht ausweichen und daher keinen WW:Abwehr würfeln.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 10,
"range": [
61,
70
],
"drawn": false
},
{
"_id": "o6r0hJ0iufMsINa1",
"flags": {},
"type": 0,
"text": "<h3>Der Angegriffene verstaucht sich den Fuß.</h3>Die Bewegungsweite verringert sich für [[2d6]] Runden um ein Drittel.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 10,
"range": [
71,
80
],
"drawn": false
},
{
"_id": "azc8c9daJPxkmg1P",
"flags": {},
"type": 0,
"text": "<h3>Der Verteidiger prallt unglücklich mit seinem Gegner zusammen (Nahkampf und Handgemenge) oder gegen ein Hindernis (Fernkampf) und ist kurzzeitig benommen.</h3>Im Nahkampf oder Handgemenge kann er in der folgenden Runde weder angreifen noch abwehren. Sein Gegner leidet unter denselben Folgen - aber nur, wenn ihm ein PW:Gewandtheit misslingt. Im Fernkampf kann der Angegriffene wie bei 61-70 dem nächsten Schuss nicht ausweichen und darf außerdem in dieser und der folgenden Runde nicht mehr angreifen.<p>61-70</p>Im Fernkampf kann der Angegriffene dem nächsten Schuss oder Wurf (in der laufenden oder folgenden Runde, nicht aber später) nicht ausweichen und daher keinen WW:Abwehr würfeln.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 10,
"range": [
81,
90
],
"drawn": false
},
{
"_id": "fT5NKtySSqN8Yzlu",
"flags": {},
"type": 0,
"text": "<h3>Der Angegriffene rutscht aus und stürzt zu Boden.</h3>Im Handgemenge hat dieser Wurf dieselben Folgen wie 61-70.<p>61-70</p>Im Nahkampf oder Handgemenge darf der Angreifer sofort außer der Reihe einen zusätzlichen EW:Angriff machen, der nicht abgewehrt werden darf.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 9,
"range": [
91,
99
],
"drawn": false
},
{
"_id": "gxzElw6oBZTjj15Z",
"flags": {},
"type": 0,
"text": "<h3>Der Angegriffene stürzt und verliert das Bewusstsein.</h3>Er kommt nach [[1d6]] Runden wieder zu sich.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 1,
"range": [
100,
100
],
"drawn": false
}
],
"formula": "1d100",
"replacement": true,
"displayRoll": true,
"_id": "XKbuKI8F08WdFfWV"
}

View File

@ -1,261 +0,0 @@
{
"name": "Kritischer Schaden",
"permission": {
"default": 2,
"CBq5YXAqbO7HoJ03": 3
},
"flags": {
"exportSource": {
"world": "midgard-test",
"system": "midgard5",
"coreVersion": "0.7.9",
"systemVersion": 0.02
}
},
"img": "icons/svg/d20-highlight.svg",
"description": "<h2>Tabelle 7: Kritischer Schaden</h2><h3>Die Folgen schwerer Verletzungen werden auf S. 63 (Kodex) beschrieben.\nEin Treffer hat besonders schwerwiegende Folgen (mit * markiert), wenn die Lebenspunkteverluste ein Drittel des LP-Maximums übersteigen. \nKostet ein kritischer Treffer das Opfer einschließlich der Zusatzschäden keine LP, richtet er keine längerfristigen Schädenan. Gliedmaßen (+) sind nur geprellt und nach 30 min wieder einsatzbereit. Ein Kopf- oder Wirbelsäulentreffer (++) macht nur wegen Schmerzen 30 min lang handlungsunfähig. Treffer im Gesicht/am Auge haben keine besonderen Auswirkungen.</h3>",
"results": [
{
"_id": "YXyhoVz5EAMuc05m",
"flags": {},
"type": 0,
"text": "<h3>normaler schwerer Schaden</h3>",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 10,
"range": [
1,
10
],
"drawn": false
},
{
"_id": "jwBN8gCTqMgaPuc4",
"flags": {},
"type": 0,
"text": "<h3>kurzer SchockDas Opfer kann durch den Schock der Verwundung eine Runde lang nicht angreifen.</h3>",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 10,
"range": [
11,
20
],
"drawn": false
},
{
"_id": "g1zQk3AHDdlq3sqH",
"flags": {},
"type": 0,
"text": "<h3>Rumpftreffer mit Rippenbrüchen</h3>[[1d3]] Rippen des Opfers brechen.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 10,
"range": [
21,
30
],
"drawn": false
},
{
"_id": "XdF7xn83ChS4Qrzf",
"flags": {},
"type": 0,
"text": "<h3>Rumpftreffer mit Gefahr innerer Verletzungen</h3>Das Opfer verliert zusätzlich zum normalen Schaden [[1d6]] LP und AP.<br /><b>*</b>: Schwere innere Verletzungen",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 5,
"range": [
31,
35
],
"drawn": false
},
{
"_id": "UjqhkUyUaBZ7n6CC",
"flags": {},
"type": 0,
"text": "<h3>schwere Verletzung der Wirbelsäule <b>++</b></h3>Nur ein wuchtiger Hieb, z.B. mit einer Schlagwaffe, einer zweihändigen Hiebwaffe, einem Morgenstern, einem Kampfstab oder mit einer Pranke, richtet diese Art von kritischem Schaden an. Treffer mit anderen Waffen verursachen normalen schweren Schaden.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 5,
"range": [
36,
40
],
"drawn": false
},
{
"_id": "W7yzr5lC0z5NDt77",
"flags": {},
"type": 0,
"text": "<h3>schwere Verletzung am rechten Arm <b>+</b></h3><b>*</b>: Mit 20% wird der Arm abgetrennt (bei einer Waffe mit Schneide) oder dauerhaft verkrüppelt. Mit Armschutz führt auch der Treffer mit einer scharfen Waffe nicht zum Abtrennen, sondern nur zur Verkrüppelung des Armes. Treffer mit Stich-, Wurf- oder Schusswaffen haben keine derart schwerwiegenden Auswirkungen.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 7,
"range": [
41,
47
],
"drawn": false
},
{
"_id": "1dFkXxy7VhtSbahw",
"flags": {},
"type": 0,
"text": "<h3>schwere Verletzung am linken Arm <b>+</b></h3><b>*</b>: Mit 20% wird der Arm abgetrennt (bei einer Waffe mit Schneide) oder dauerhaft verkrüppelt. Mit Armschutz führt auch der Treffer mit einer scharfen Waffe nicht zum Abtrennen, sondern nur zur Verkrüppelung des Armes. Treffer mit Stich-, Wurf- oder Schusswaffen haben keine derart schwerwiegenden Auswirkungen.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 8,
"range": [
48,
55
],
"drawn": false
},
{
"_id": "CiAwKT1ZhOGKplBr",
"flags": {},
"type": 0,
"text": "<h3>schwere Verletzung am rechten Bein <b>+</b></h3><b>*</b>: Mit 20% wird das Bein abgetrennt (ohne Beinschutz bei einer Waffe mit Schneide) oder dauerhaft verkrüppelt. Treffer mit Stich-, Wurf- oder Schusswaffen haben keine derart schwerwiegenden Auswirkungen.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 9,
"range": [
56,
64
],
"drawn": false
},
{
"_id": "PZa6plWsSiQFmu5c",
"flags": {},
"type": 0,
"text": "<h3>schwere Verletzung am linken Bein <b>+</b></h3><b>*</b>: Mit 20% wird das Bein abgetrennt (ohne Beinschutz bei einer Waffe mit Schneide) oder dauerhaft verkrüppelt. Treffer mit Stich-, Wurf- oder Schusswaffen haben keine derart schwerwiegenden Auswirkungen.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 9,
"range": [
65,
73
],
"drawn": false
},
{
"_id": "5xXKfpkaOap9WV0o",
"flags": {},
"type": 0,
"text": "<h3>schwerer Kopftreffer <b>++</b></h3>Helmlose Opfer verlieren zusätzlich zum normalen Schaden [[1d3]] LP und AP.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 7,
"range": [
74,
80
],
"drawn": false
},
{
"_id": "5OTWkWQxchPs6SQI",
"flags": {},
"type": 0,
"text": "<h3>Treffer im Gesicht</h3>Das Aussehen des Getroffenen sinkt durch eine entstellende Narbe dauerhaft um ein Zehntel (mindestens aber um 1). Der Träger eines Helms mit Visier ist vor dieser Art von Schaden sicher.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 5,
"range": [
81,
85
],
"drawn": false
},
{
"_id": "GaZZENfKk81MI1IK",
"flags": {},
"type": 0,
"text": "<h3>Kopftreffer mit Hörschaden <b>&lt;++&gt;</b></h3>Helmlose Opfer verlieren zusätzlich zum normalen Schaden [[1d3]] LP und AP. Zusätzlich schwere Verletzung am Ohr. Helmträger sind vor dieser Art von Schaden sicher.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 4,
"range": [
86,
89
],
"drawn": false
},
{
"_id": "OsfxiUi4dg0RM9XV",
"flags": {},
"type": 0,
"text": "<h3>Augenverletzung</h3>Der Träger eines Helms mit Visier ist vor dieser Art von Schaden sicher.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 4,
"range": [
90,
93
],
"drawn": false
},
{
"_id": "TGtUlGPANVjZLgZH",
"flags": {},
"type": 0,
"text": "<h3>Halstreffer</h3><b>*</b>: Eine spitze oder scharfe Waffe verletzt die Halsschlagader. Eine stumpfe Waffe verursacht eine schwere Halswirbelverletzung.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 3,
"range": [
94,
96
],
"drawn": false
},
{
"_id": "98WnvS1A35Vr0rOv",
"flags": {},
"type": 0,
"text": "<h3>schwere Schädelverletzung <b>++</b></h3>Helmlose Opfer verlieren zusätzlich zum normalen Schaden [[1d6]] LP und AP. Fällt das Opfer ins Koma, sinkt seine Intelligenz durch Hirnschäden dauerhaft um ein Zehntel (mindestens aber um 1).",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 1,
"range": [
97,
97
],
"drawn": false
},
{
"_id": "8g1FJIsxKFVWvyxe",
"flags": {},
"type": 0,
"text": "<h3>Augenverlust</h3>Bei einem Treffer mit einer scharfen oder spitzen Waffe oder einer Schusswaffe verliert das Opfer ein Auge. Der Träger eines Helms mit Visier ist vor dieser Art von Schaden sicher.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 2,
"range": [
98,
99
],
"drawn": false
},
{
"_id": "U1SXJI4yzfzcQM01",
"flags": {},
"type": 0,
"text": "<h3>tödlicher Treffer</h3>Ein Treffer ins Herz, an der Kehle usw. tötet den Getroffenen augenblicklich.",
"img": "icons/svg/d20-black.svg",
"resultId": "",
"weight": 1,
"range": [
100,
100
],
"drawn": false
}
],
"formula": "1d100",
"replacement": true,
"displayRoll": true,
"_id": "cQX6GAYWErokE8ks"
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,20 +1,30 @@
import Globals from "./Globals"
import Globals from "./Globals";
const preloadTemplates = async (): Promise<Handlebars.TemplateDelegate<any>[]> => {
const rootPath = `${Globals.isModule ? "modules" : "systems"}/${Globals.name}/templates/`
const rootPath = `${Globals.isModule ? "modules" : "systems"}/${Globals.name}/templates/`;
// Place relative paths in array below, e.g.:
// const templates = [ rootPath + "actor/actor-sheet.hbs" ]
// This would map to our local folder of /Assets/Templates/Actor/actor-sheet.hbs
const templates: Array<string> = [
"sheets/character/description.hbs",
"sheets/character/attribute.hbs",
"sheets/character/base_values.hbs",
"sheets/character/main.hbs",
"sheets/character/skills.hbs",
"sheets/character/gear.hbs",
"sheets/character/spells.hbs",
"sheets/character/combat.hbs",
"sheets/character/effects.hbs",
"sheets/npc/main.hbs",
"sheets/npc/combat.hbs",
"sheets/npc/properties.hbs",
"sheets/npc/description.hbs",
"sheets/npc/attribute.hbs",
"sheets/partial/mod.hbs",
"sheets/item/rolls.hbs",
"chat/roll-m5.hbs"
]
return loadTemplates(templates.map(s => rootPath + s))
}
"chat/roll-m5.hbs",
];
return loadTemplates(templates.map((s) => rootPath + s));
};
export default preloadTemplates
export default preloadTemplates;

114
source/helpers.ts Normal file
View File

@ -0,0 +1,114 @@
/* global Handlebars, game, TextEditor, WOD5E */
import { M5Skill } from "./module/M5Base";
import { M5Character } from "./module/actors/M5Character";
/**
* Define any helpers necessary for working with Handlebars
* @return {Promise}
*/
export const loadHelpers = async function () {
Handlebars.registerHelper("times", (n: number, block) => {
var accum = "";
for (let i = 0; i < n; ++i) accum += block.fn(i);
return accum;
});
Handlebars.registerHelper("array", (arr: any[], index: number) => {
return arr[index];
});
Handlebars.registerHelper("m5concat", (...values) => {
const options = values.pop();
const join = options.hash?.join || "";
//return new Handlebars.SafeString(values.join(join));
return values.map((val) => val.toString()).join(join);
});
Handlebars.registerHelper("add", (...values) => {
const options = values.pop();
return values.reduce((prev, cur) => prev + cur);
});
Handlebars.registerHelper("localizeMidgard", (str: string) => {
const template = Handlebars.compile("{{localize value}}");
return template({
value: "midgard5." + str,
});
});
Handlebars.registerHelper("skillBonus", (actorId: string, skill: M5Skill) => {
const actor = (game as Game).actors.get(actorId) as M5Character;
return actor.skillBonus(skill).toString();
});
Handlebars.registerHelper("skillEw", (actorId: string, skill: M5Skill) => {
const actor = (game as Game).actors.get(actorId) as M5Character;
return actor.skillEw(skill).toString();
});
Handlebars.registerHelper("skill", (skillId: string) => {
return (game as Game).items.get(skillId);
});
Handlebars.registerHelper("itemValue", (id: string, path: string) => {
let obj = (game as Game).items.get(id);
path.split(".").forEach((p) => (obj = obj[p]));
return `${obj}`;
});
Handlebars.registerHelper("actorItemValue", (actorId: any, itemId: string, path: string, token?: boolean) => {
//console.log("actorItemValue", actorId, itemId, path)
const actor = (game as Game).actors.get(actorId);
let obj = actor.items.get(itemId)?.system;
path.split(".").forEach((p) => {
if (obj) obj = obj[p];
});
return `${obj}`;
});
Handlebars.registerHelper("icon", (relpath: string) => {
return `systems/midgard5/assets/icons/${relpath}`;
});
Handlebars.registerHelper("isSkillInList", (skillName: string, list: any) => {
for (let key in list) {
if (list[key]?.label?.toLowerCase() === skillName?.toLowerCase()) {
return true;
}
}
return false;
});
Handlebars.registerHelper("skillEwInList", (skillName: string, list: any) => {
for (let key in list) {
if (list[key]?.label?.toLowerCase() === skillName?.toLowerCase()) {
return list[key].calc.ew;
}
}
return false;
});
Handlebars.registerHelper("stripHtml", function (param) {
var regex = /(<([^>]+)>)/gi;
return param.replace(regex, "");
});
Handlebars.registerHelper("contains", (label: string, contains: string) => {
return label.toLowerCase().includes(contains.toLowerCase());
});
Handlebars.registerHelper("count", (object: any) => {
var length = 0;
for (var key in object) {
if (object.hasOwnProperty(key)) {
++length;
}
}
return length;
});
Handlebars.registerHelper("console", (object: any) => {
console.log(object);
});
};

View File

@ -1,98 +1,203 @@
import Logger from "./utils/Logger"
import M5CharacterSheet from "./module/sheets/M5CharacterSheet"
import preloadTemplates from "./PreloadTemplates"
import { M5Character } from "./module/actors/M5Character"
import { M5Skill } from "./module/M5Base"
import { M5ItemSheet } from "./module/sheets/M5ItemSheet"
import { M5Item } from "./module/items/M5Item"
import Logger from "./utils/Logger";
import M5CharacterSheet from "./module/sheets/M5CharacterSheet";
import preloadTemplates from "./PreloadTemplates";
import { M5Character } from "./module/actors/M5Character";
import { M5ModOperation, M5TimeUnit } from "./module/M5Base";
import { M5ItemSheet } from "./module/sheets/M5ItemSheet";
import { M5Item } from "./module/items/M5Item";
import { reroll } from "./module/rolls/reroll";
import { loadHelpers } from "./helpers";
import { loadSettings } from "./settings";
Hooks.once("init", async () => {
Logger.log("M5 | Initialisierung Midgard 5")
Logger.log("M5 | Initialisierung Midgard 5");
Handlebars.registerHelper("times", (n: number, block) => {
var accum = ""
for(let i = 0; i < n; ++i)
accum += block.fn(i)
return accum
})
Handlebars.registerHelper("array", (arr: any[], index: number) => {
return arr[index]
})
Handlebars.registerHelper("m5concat", (...values) => {
const options = values.pop();
const join = options.hash?.join || "";
//return new Handlebars.SafeString(values.join(join));
return values.map(val => val.toString()).join(join)
})
Handlebars.registerHelper("add", (...values) => {
const options = values.pop();
return values.reduce((prev, cur) => prev + cur)
})
Handlebars.registerHelper("localizeMidgard", (str: string) => {
const template = Handlebars.compile("{{localize value}}")
return template({
value: "midgard5." + str
})
})
Handlebars.registerHelper("skillBonus", (actorId: string, skill: M5Skill) => {
const actor = (game as Game).actors.get(actorId) as M5Character
return actor.skillBonus(skill).toString()
})
Handlebars.registerHelper("skillEw", (actorId: string, skill: M5Skill) => {
const actor = (game as Game).actors.get(actorId) as M5Character
return actor.skillEw(skill).toString()
})
Handlebars.registerHelper("skill", (skillId: string) => {
return (game as Game).items.get(skillId)
})
Handlebars.registerHelper("itemValue", (id: string, path: string) => {
let obj = (game as Game).items.get(id)
path.split(".").forEach(p => obj = obj[p])
return `${obj}`
})
Handlebars.registerHelper("actorItemValue", (actorId: any, itemId: string, path: string) => {
//console.log("actorItemValue", actorId, itemId, path)
const actor = (game as Game).actors.get(actorId)
let obj = actor.items.get(itemId).system
path.split(".").forEach(p => {
if (obj)
obj = obj[p]
})
return `${obj}`
})
Handlebars.registerHelper("icon", (relpath: string) => {
return `systems/midgard5/assets/icons/${relpath}`
})
// Load settings into Foundry
loadSettings();
// Default Sheet für Items definieren und das Standardsheet deaktivieren
Items.unregisterSheet("core", ItemSheet)
Items.registerSheet("midgard5", M5ItemSheet, { makeDefault: true })
Items.unregisterSheet("core", ItemSheet);
Items.registerSheet("midgard5", M5ItemSheet, { makeDefault: true });
// Default Sheet für Actors definieren und das Standardsheet deaktivieren
Actors.unregisterSheet("core", ActorSheet)
Actors.registerSheet("midgard5", M5CharacterSheet, { makeDefault: true })
CONFIG.Actor.documentClass = M5Character
CONFIG.Item.documentClass = M5Item
Actors.unregisterSheet("core", ActorSheet);
Actors.registerSheet("midgard5", M5CharacterSheet, { makeDefault: true });
CONFIG.Actor.documentClass = M5Character;
CONFIG.Item.documentClass = M5Item;
//RegisterSettings();
await preloadTemplates()
})
await preloadTemplates();
loadHelpers();
});
Hooks.once("setup", () => {
Logger.log("Template module is being setup.")
})
Logger.log("Template module is being setup.");
});
Hooks.on("getChatLogEntryContext", function (html, options) {
options.push(
{
name: "LP & AP Schaden",
icon: '<i class="fas fa-tint"></i>',
condition: (li) => {
const damageRolls = li.find(".damage").length;
// All must be true to show the reroll dialogue
return (game["user"].character || game["canvas"].tokens.controlled) && damageRolls > 0;
},
callback: (li) => applyDamage(li, 2),
},
{
name: "AP Schaden",
icon: '<i class="fas fa-shield-alt"></i>',
condition: (li) => {
const damageRolls = li.find(".damage").length;
// All must be true to show the reroll dialogue
return (game["user"].character || game["canvas"].tokens.controlled) && damageRolls > 0;
},
callback: (li) => applyDamage(li, 1),
},
{
name: "LP & AP Heilen",
icon: '<i class="fas fa-heart"></i>',
condition: (li) => {
const damageRolls = li.find(".heal").length;
// All must be true to show the reroll dialogue
return (game["user"].character || game["canvas"].tokens.controlled) && damageRolls > 0;
},
callback: (li) => applyDamage(li, -1),
},
{
name: "AP Heilen",
icon: '<i class="far fa-heart"></i>',
condition: (li) => {
const damageRolls = li.find(".heal").length;
// All must be true to show the reroll dialogue
return (game["user"].character || game["canvas"].tokens.controlled) && damageRolls > 0;
},
callback: (li) => applyDamage(li, -2),
},
{
name: "Redo",
icon: '<i class="far fa-arrow-rotate-left"></i>',
condition: (li) => {
const message = (game as Game).messages.get(li.attr("data-message-id"));
// All must be true to show the reroll dialogue
return (game["user"].isGM || game["user"].character?.id === (game as Game).actors.get(message["speaker"].actor)?.id) && !message["flags"].rerolled;
},
callback: (li) => reroll(li),
}
);
});
Hooks.on("updateCombat", function (combat: Combat, updateData: { round: number; turn: number }, updateOptions: { advanceTime: number; direction: number }) {
if (combat.round % 2 === 0 && combat.turn !== null) {
const tokenId = combat.current.tokenId;
const actorId = combat.combatant["actorId"];
let currentToken = game["actors"].tokens[tokenId];
if (!currentToken) {
currentToken = game["actors"].get(actorId);
}
let activeEffects = currentToken.items.filter((x) => x.type === "effect" && x.system.equipped) || [];
activeEffects.forEach((effect) => {
if (effect.system?.duration?.time > 0) {
if (effect.system.duration.unit === M5TimeUnit.ROUND) {
effect.system.duration.time -= 1;
}
}
if (effect.system?.duration.time === 0 && effect.system.duration.unit !== M5TimeUnit.LIMITLESS) {
effect.system.equipped = false;
}
for (const key in effect.system.mods) {
if (effect.system.mods[key].operation === M5ModOperation.SUBTRACT) {
switch (effect.system.mods[key].id) {
case "lp":
currentToken["system"].lp.value -= effect.system.mods[key].value;
break;
case "ap":
currentToken["system"].ap.value -= effect.system.mods[key].value;
break;
}
} else if (effect.system.mods[key].operation === M5ModOperation.ADD) {
switch (effect.system.mods[key].id) {
case "lp":
currentToken["system"].lp.value += limitHeal(effect.system.mods[key].value, currentToken["system"].lp.value, currentToken["system"].lp.max);
break;
case "ap":
currentToken["system"].ap.value += limitHeal(effect.system.mods[key].value, currentToken["system"].ap.value, currentToken["system"].ap.max);
break;
}
}
}
});
currentToken.render();
}
});
Hooks.on("renderCombatTracker", (combatTracker, html, context) => {
if (context.combat === null) {
html.find("h3.encounter-title")[0].innerHTML = game["i18n"].localize("midgard5.no-encounter");
} else if (Math.ceil(context.round / 2) === 0) {
html.find("h3.encounter-title")[0].innerHTML = game["i18n"].localize("midgard5.encounter-not-started");
} else {
html.find("h3.encounter-title")[0].innerHTML =
(context.round % 2 == 1 ? game["i18n"].localize("midgard5.phase-movement") : game["i18n"].localize("midgard5.phase-action")) + " " + Math.ceil(context.round / 2);
}
});
Hooks.once("ready", () => {
Logger.ok("Template module is now ready.")
})
Logger.ok("Template module is now ready.");
});
async function applyDamage(roll, direction) {
const damageValue = Array.from(roll.find(".apply") as HTMLElement[])
.map((x) => Math.max(0, Number(x.innerText)))
.reduce((prev, curr) => prev + curr, 0);
const controlledTokens = game["canvas"].tokens.controlled;
const actor = game["user"].character;
if (controlledTokens) {
controlledTokens.forEach((controlledToken) => {
let token = controlledToken.document.delta.syntheticActor;
switch (direction) {
case 2:
token["system"].lp.value -= Math.max(0, damageValue - token["system"].calc.stats.lpProtection.value);
case 1:
token["system"].ap.value -= Math.max(0, damageValue - token["system"].calc.stats.apProtection.value);
break;
case -1:
token["system"].lp.value += limitHeal(damageValue, token["system"].lp.value, token["system"].lp.max);
case -2:
token["system"].ap.value += limitHeal(damageValue, token["system"].ap.value, token["system"].ap.max);
}
token.render();
});
} else {
switch (direction) {
case 2:
actor["system"].lp.value -= Math.max(0, damageValue - actor["system"].calc.stats.lpProtection.value);
case 1:
actor["system"].ap.value -= Math.max(0, damageValue - actor["system"].calc.stats.apProtection.value);
break;
case -1:
actor["system"].lp.value += limitHeal(damageValue, actor["system"].lp.value, actor["system"].lp.max);
case -2:
actor["system"].ap.value += limitHeal(damageValue, actor["system"].ap.value, actor["system"].ap.max);
}
actor.render();
}
}
function limitHeal(heal: number, current: number, max: number): number {
if (current === max) {
return 0;
} else if (heal + current > max) {
return max - current;
}
return heal;
}

View File

@ -1,52 +1,72 @@
import { BooleanField } from "@league-of-foundry-developers/foundry-vtt-types/src/foundry/common/data/fields.mjs"
import { BooleanField } from "@league-of-foundry-developers/foundry-vtt-types/src/foundry/common/data/fields.mjs";
export interface M5Skill {
fw: number
attribute: string
pp: number
fw: number;
attribute: string;
pp: number;
}
export interface M5SkillUnlearned extends M5Skill {
initial: number
initial: number;
}
export interface M5SkillLearned extends M5Skill {
skill: string
type: string
skill: string;
type: string;
}
export interface M5SkillCalculated extends M5Skill {
label: string,
calc: any
label: string;
calc: any;
}
export interface M5Attribute {
value: number
bonus: number
value: number;
bonus: number;
}
export interface M5RollData {
c: any
i: any
iType: string
rolls: {}
c: any;
i: any;
b: any;
iType: string;
rolls: any;
res: {
label: string
}
label: string;
};
}
export interface M5RollTemplate {
formula: string
label: string
enabled: boolean
formula: string;
label: string;
enabled: boolean;
}
export interface M5RollResult extends M5RollTemplate {
total: number
totalStr: string
result: string
dice: {}
css: string
total: number;
totalStr: string;
result: string;
dice: {};
css: string;
}
export enum M5ItemType {
SKILL = "skill",
ITEM = "item",
WEAPON = "weapon",
DEFENSIVE_WEAPON = "defensiveWeapon",
ARMOR = "armor",
CONTAINER = "container",
SPELL = "spell",
KAMPFKUNST = "kampfkunst",
EFFECT = "effect",
}
export enum M5SkillType {
INNATE = "innate",
GENERAL = "general",
LANGUAGE = "language",
COMBAT = "combat",
}
export enum M5EwResult {
@ -55,7 +75,7 @@ export enum M5EwResult {
CRITICAL = "roll-ew-result-critical",
HIGH = "roll-ew-result-high",
FAIL = "roll-ew-result-fail",
PASS = "roll-ew-result-pass"
PASS = "roll-ew-result-pass",
}
export enum M5Attributes {
@ -67,7 +87,7 @@ export enum M5Attributes {
ZT = "zt",
AU = "au",
PA = "pa",
WK = "wk"
WK = "wk",
}
export enum M5Stats {
@ -81,96 +101,130 @@ export enum M5Stats {
BRAWL = "brawl",
POISON_RESISTANCE = "poisonResistance",
LP = "lp",
AP = "ap"
AP = "ap",
PROTECTION_LP = "lpProtection",
PROTECTION_AP = "apProtection",
DEPRIVATION_COLD = "deprivationCold",
DEPRIVATION_HEAT = "deprivationHeat",
DEPRIVATION_FOOD = "deprivationFood",
}
export enum M5ModType {
ATTRIBUTE = "attribute",
STAT = "stat",
SKILL = "skill"
SKILL = "skill",
}
export enum M5ModOperation {
ADD_100 = "add100",
ROLL = "roll",
ADD = "add",
SET = "set",
FIXED = "fixed"
FIXED = "fixed",
MULTIPLY = "multiply",
SUBTRACT = "subtract",
DIVISION = "division",
}
export enum M5TimeUnit {
ROUND = "round",
MINUTE = "minute",
HOUR = "hour",
LIMITLESS = "limitless",
}
export interface M5ItemMod {
type: M5ModType
id: string
operation: M5ModOperation
value: number
type: M5ModType;
id: string;
operation: M5ModOperation;
value: number;
}
export interface M5ModPair {
mod: M5ItemMod
source: string
mod: M5ItemMod;
source: string;
}
export interface M5ModSource {
item: string
operation: M5ModOperation
value: number
item: string;
operation: M5ModOperation;
value: number;
}
export interface M5ModResult {
mods: Array<M5ModSource>
value: number
mods: Array<M5ModSource>;
value: number;
}
export interface M5AttributeCalculated extends M5ModResult {
bonus: number
bonus: number;
}
export interface M5CharacterCalculatedData {
level: number
level: number;
movement: number;
attributes: {
st: M5AttributeCalculated
gs: M5AttributeCalculated
gw: M5AttributeCalculated
ko: M5AttributeCalculated
in: M5AttributeCalculated
zt: M5AttributeCalculated
au: M5AttributeCalculated
pa: M5AttributeCalculated
wk: M5AttributeCalculated
}
st: M5AttributeCalculated;
gs: M5AttributeCalculated;
gw: M5AttributeCalculated;
ko: M5AttributeCalculated;
in: M5AttributeCalculated;
zt: M5AttributeCalculated;
au: M5AttributeCalculated;
pa: M5AttributeCalculated;
wk: M5AttributeCalculated;
};
stats: {
lp: M5ModResult
ap: M5ModResult
armor: number
defense: M5ModResult
damageBonus: M5ModResult
attackBonus: M5ModResult
defenseBonus: M5ModResult
movementBonus: M5ModResult
resistanceMind: M5ModResult
resistanceBody: M5ModResult
spellCasting: M5ModResult
brawl: M5ModResult
brawlEw: number
poisonResistance: M5ModResult
enduranceBonus: number
}
skillMods: {}
lp: M5ModResult;
ap: M5ModResult;
lpProtection: M5ModResult;
apProtection: M5ModResult;
defense: M5ModResult;
damageBonus: M5ModResult;
attackBonus: M5ModResult;
defenseBonus: M5ModResult;
movement: M5ModResult;
resistanceMind: M5ModResult;
resistanceBody: M5ModResult;
spellCasting: M5ModResult;
brawl: M5ModResult;
brawlFw: number;
poisonResistance: M5ModResult;
enduranceBonus: number;
deprivationCold: M5ModResult;
deprivationHeat: M5ModResult;
deprivationFood: M5ModResult;
hoard: number;
hoardNext: number;
hoardMin: number;
wealth: number;
load: number;
heavyLoad: number;
loadMax: number;
thrustLoad: number;
encumbrance: number;
};
skillMods: {};
skills: {
innate: {}
general: {}
combat: {}
language: {}
custom: {}
}
innate: {};
general: {};
combat: {};
language: {};
custom: {};
};
gear: {
weapons: {}
defensiveWeapons: {}
armor: {}
items: {}
}
spells: {}
weapons: {};
defensiveWeapons: {};
armor: {};
items: {};
containers: {};
effects: {};
};
spells: {};
kampfkuenste: {};
}
export function enumKeys<O extends object, K extends keyof O = keyof O>(obj: O): K[] {
return Object.keys(obj).filter(k => Number.isNaN(+k)) as K[]
return Object.keys(obj).filter((k) => Number.isNaN(+k)) as K[];
}

View File

@ -1,7 +1,6 @@
import { M5Item } from "../items/M5Item";
import { M5Attribute, M5CharacterCalculatedData, M5ItemMod, M5ModOperation, M5ModResult, M5RollData, M5Skill, M5SkillCalculated, M5SkillLearned } from "../M5Base";
import { M5Attribute, M5CharacterCalculatedData, M5ItemMod, M5ItemType, M5ModOperation, M5ModResult, M5RollData, M5Skill, M5SkillCalculated } from "../M5Base";
import M5ModAggregate from "./M5ModAggregate";
export class M5Character extends Actor {
// constructor(
// data: ConstructorParameters<typeof foundry.documents.BaseActor>[0],
@ -24,7 +23,67 @@ export class M5Character extends Actor {
return -2;
}
derivedData(skip: { mods?: boolean; skills?: boolean; weapons?: boolean; defensiveWeapons?: boolean; armor?: boolean; items?: boolean; spells?: boolean } = {}): M5CharacterCalculatedData {
static loadValue(attribute: M5Attribute) {
const value = this.attributeMinMax(attribute);
if (value > 99) return 35;
if (value > 95) return 30;
if (value > 80) return 25;
if (value > 60) return 20;
if (value > 30) return 15;
if (value > 10) return 10;
if (value > 0) return 5;
return 0;
}
static heavyLoadValue(attribute: M5Attribute) {
const value = this.attributeMinMax(attribute);
if (value > 99) return 50;
if (value > 95) return 45;
if (value > 80) return 40;
if (value > 60) return 35;
if (value > 30) return 30;
if (value > 10) return 25;
if (value > 0) return 20;
return 0;
}
static maxLoadValue(attribute: M5Attribute) {
const value = this.attributeMinMax(attribute);
if (value > 99) return 90;
if (value > 95) return 80;
if (value > 80) return 75;
if (value > 60) return 70;
if (value > 30) return 60;
if (value > 10) return 50;
if (value > 0) return 40;
return 0;
}
static thrustLoadValue(attribute: M5Attribute) {
const value = this.attributeMinMax(attribute);
if (value > 99) return 200;
if (value > 95) return 170;
if (value > 80) return 150;
if (value > 60) return 140;
if (value > 30) return 120;
if (value > 10) return 70;
if (value > 0) return 50;
return 0;
}
derivedData(
skip: {
mods?: boolean;
skills?: boolean;
items?: boolean;
spells?: boolean;
effects?: boolean;
containers?: boolean;
kampfkuenste?: boolean;
encumbrance?: boolean;
class?: boolean;
} = {}
): M5CharacterCalculatedData {
let ret: M5CharacterCalculatedData = {
level: 0,
attributes: {
@ -41,19 +100,29 @@ export class M5Character extends Actor {
stats: {
lp: { value: 0, mods: [] },
ap: { value: 0, mods: [] },
armor: 0,
lpProtection: { value: 0, mods: [] },
apProtection: { value: 0, mods: [] },
defense: { value: 0, mods: [] },
damageBonus: { value: 0, mods: [] },
attackBonus: { value: 0, mods: [] },
defenseBonus: { value: 0, mods: [] },
movementBonus: { value: 0, mods: [] },
movement: { value: 0, mods: [] },
resistanceMind: { value: 0, mods: [] },
resistanceBody: { value: 0, mods: [] },
spellCasting: { value: 0, mods: [] },
brawl: { value: 0, mods: [] },
brawlEw: 0,
brawlFw: 0,
poisonResistance: { value: 0, mods: [] },
enduranceBonus: 0,
deprivationCold: { value: 0, mods: [] },
deprivationHeat: { value: 0, mods: [] },
deprivationFood: { value: 0, mods: [] },
hoard: 0,
encumbrance: 0,
load: 0,
heavyLoad: 0,
thrustLoad: 0,
loadMax: 0,
},
skillMods: {},
skills: {
@ -68,8 +137,11 @@ export class M5Character extends Actor {
defensiveWeapons: {},
armor: {},
items: {},
containers: {},
effects: {},
},
spells: {},
kampfkuenste: {},
} as M5CharacterCalculatedData;
const context = this as any;
@ -78,8 +150,9 @@ export class M5Character extends Actor {
const data = (this as any).system;
if (!data) return null;
ret.level = M5Character.levelFromExp(data.es);
ret.level = M5Character.levelFromExp(data.info.race === "Zwerg" ? Math.min(data.calc.stats?.hoard * 2 || 0, data.es) : data.es);
//Set all values that are not dependent on another Value
ret.attributes.st.value = M5Character.attributeMinMax(data.attributes.st); // TODO item effects
ret.attributes.gs.value = M5Character.attributeMinMax(data.attributes.gs);
ret.attributes.gw.value = M5Character.attributeMinMax(data.attributes.gw);
@ -102,25 +175,23 @@ export class M5Character extends Actor {
ret.stats.lp = this.modResult(data.lp);
ret.stats.ap = this.modResult(data.ap);
ret.stats.armor = 0;
ret.stats.defense = this.modResult(M5Character.defenseFromLevel(ret.level));
ret.stats.damageBonus = this.modResult(Math.floor(ret.attributes.st.value / 20) + Math.floor(ret.attributes.gs.value / 30) - 3);
ret.stats.attackBonus = this.modResult(ret.attributes.gs.bonus);
ret.stats.defenseBonus = this.modResult(ret.attributes.gw.bonus);
ret.stats.movementBonus = this.modResult(0);
ret.stats.resistanceMind = this.modResult(ret.stats.defense.value);
ret.stats.resistanceBody = this.modResult(ret.stats.defense.value + 1);
ret.stats.spellCasting = this.modResult((data.info.magicUsing ? M5Character.spellCastingFromLevel(ret.level) : 3) + ret.attributes.zt.bonus);
ret.stats.brawl = this.modResult(Math.floor((ret.attributes.st.value + ret.attributes.gw.value) / 20));
ret.stats.brawlEw = ret.stats.brawl.value + ret.stats.attackBonus.value;
ret.stats.poisonResistance = this.modResult(30 + Math.floor(ret.attributes.ko.value / 2));
ret.stats.enduranceBonus = Math.floor(ret.attributes.ko.value / 10) + Math.floor(ret.attributes.st.value / 20);
ret.stats.lpProtection = this.modResult(0);
ret.stats.apProtection = this.modResult(0);
ret.stats.movement = this.modResult(data.movement);
ret.stats.hoardMin = M5Character.levelThreshold.at(ret.level - 1) / 2;
ret.stats.hoardNext = M5Character.levelThreshold.at(ret.level) / 2;
ret.stats.wealth = parseFloat((data.info.gold + data.info.silver / 10 + data.info.copper / 100).toPrecision(10));
ret.stats.hoard = 0;
ret.stats.encumbrance = 0;
if (!skip?.mods) {
const aggregate = new M5ModAggregate(data, ret);
context.items
?.filter((item) => item.type === "item")
?.filter(
(item) =>
(item.type === "item" || item.type === "skill" || item.type === "effect" || item.type === "armor" || item.type === "container" || item.type === "class") && item.system.equipped
)
.forEach((item) => {
const mods = item.system.mods;
//console.log("Actor item mods", mods)
@ -133,9 +204,49 @@ export class M5Character extends Actor {
ret.skillMods = aggregate.calculate();
}
if (!skip?.items) {
ret.stats.defense = this.modResult(M5Character.defenseFromLevel(ret.level));
ret.stats.damageBonus = this.modResult(Math.floor(ret.attributes.st.value / 20) + Math.floor(ret.attributes.gs.value / 30) - 3);
ret.stats.attackBonus = this.modResult(ret.attributes.gs.bonus);
ret.stats.defenseBonus = this.modResult(ret.attributes.gw.bonus);
ret.stats.resistanceMind = this.modResult(ret.stats.defense.value + (data.info.race === "Mensch" ? ret.attributes.in.bonus : this.raceBonus(data.info.race)));
ret.stats.resistanceBody = this.modResult(ret.stats.defense.value + (data.info.race === "Mensch" ? ret.attributes.ko.bonus : this.raceBonus(data.info.race)));
ret.stats.spellCasting = this.modResult((data.info.magicUsing ? M5Character.spellCastingFromLevel(ret.level) : 3) + ret.attributes.zt.bonus);
ret.stats.brawl = this.modResult(Math.floor((ret.attributes.st.value + ret.attributes.gw.value) / 20));
ret.stats.brawlFw = ret.stats.brawl.value + ret.stats.attackBonus.value + (data.info.race === "Zwerg" ? 1 : 0);
ret.stats.poisonResistance = this.modResult(30 + Math.floor(ret.attributes.ko.value / 2));
ret.stats.enduranceBonus = Math.floor(ret.attributes.ko.value / 10) + Math.floor(ret.attributes.st.value / 20);
ret.stats.deprivationCold = this.modResult(Math.floor(ret.attributes.ko.value / 2));
ret.stats.deprivationHeat = this.modResult(Math.floor(ret.attributes.ko.value / 2));
ret.stats.deprivationFood = this.modResult(Math.floor(40 + ret.attributes.ko.value / 2));
ret.stats.load = M5Character.loadValue(data.attributes.st);
ret.stats.heavyLoad = M5Character.heavyLoadValue(data.attributes.st);
ret.stats.loadMax = M5Character.maxLoadValue(data.attributes.st);
ret.stats.thrustLoad = M5Character.thrustLoadValue(data.attributes.st);
if (!skip?.mods) {
const aggregate = new M5ModAggregate(data, ret);
context.items
?.filter((item) => item.type === "item")
?.filter(
(item) =>
(item.type === "item" || item.type === "skill" || item.type === "effect" || item.type === "armor" || item.type === "container" || item.type === "class") && item.system.equipped
)
.forEach((item) => {
const mods = item.system.mods;
//console.log("Actor item mods", mods)
Object.keys(mods).forEach((modIndex) => {
const mod = mods[modIndex] as M5ItemMod;
aggregate.push(mod, item.name);
});
});
ret.skillMods = aggregate.calculate();
}
if (!skip?.containers) {
context.items
?.filter((item) => item.type === "container")
.sort((a, b) => a?.sort - b?.sort)
.forEach((item) => {
item.prepareDerivedData();
@ -144,33 +255,93 @@ export class M5Character extends Actor {
label += "*";
}
ret.gear.items[item.id] = {
let icon = item.img;
let rollable = false;
for (let key in item.system.rolls.formulas) {
rollable = item.system.rolls.formulas[key]?.enabled;
if (rollable) {
break;
}
}
ret.gear.containers[item.id] = {
label: label,
icon: icon,
magic: item.system.magic,
valuable: item.system?.valuable,
hoarded: item.system?.hoarded,
calc: item.system.calc,
equipped: item.system?.equipped,
weight: item.system.weight || 0,
capacity: item.system.capacity || 0,
value: item.system.value || 0,
currency: item.system.currency || "",
quantity: item.system.quantity || 0,
rollExist: rollable,
};
});
}
if (!skip?.skills) {
if (!skip?.items) {
context.items
?.filter((item) => item.type === "skill")
?.filter((item) => item.type === "item")
.sort((a, b) => a?.sort - b?.sort)
.forEach((item) => {
item.prepareDerivedData();
const skillMap = ret.skills[item.system.type];
skillMap[item.id] = {
label: item.name,
fw: item.system.fw,
attribute: item.system.attribute,
pp: item.system.pp,
calc: item.system.calc,
} as M5SkillCalculated;
});
let label = item.name;
if (item.system.magic) {
label += "*";
}
if (item.system.valuable) {
ret.stats.wealth += parseFloat(this.calculateValue(item.system.value * item.system.quantity, item.system.currency).toPrecision(3));
}
if (item.system.hoarded) {
ret.stats.hoard += parseFloat(this.calculateValue(item.system.value * item.system.quantity, item.system.currency).toPrecision(3));
}
if (!skip?.weapons) {
if (!!item.system.containerId) {
ret.gear.containers[item.system.containerId].weight += parseFloat((item.system.weight * item.system.quantity).toPrecision(4));
ret.gear.containers[item.system.containerId].value += parseFloat(this.calculateValue(item.system.value * item.system.quantity, item.system.currency).toPrecision(3));
if (ret.gear.containers[item.system.containerId].equipped) {
ret.stats.encumbrance += item.system.weight * item.system.quantity;
}
} else if (item.system.equipped) {
ret.stats.encumbrance += item.system.weight * item.system.quantity;
}
let icon = item.img;
let rollable = false;
// console.log(item.system.rolls.formulas.map((p) => p.enabled));
for (let key in item.system.rolls.formulas) {
rollable = item.system.rolls.formulas[key]?.enabled;
if (rollable) {
break;
}
}
ret.gear.items[item.id] = {
label: label,
icon: icon,
magic: item.system.magic,
abw: item.system.abw || 0,
calc: item.system.calc,
equipped: item.system?.equipped,
valuable: item.system?.valuable,
hoarded: item.system?.hoarded,
weight: item.system.weight || 0,
containerId: item.system.containerId || "",
value: item.system.value || 0,
currency: item.system.currency || "",
quantity: item.system.quantity || 0,
rollExist: rollable,
};
});
context.items
?.filter((item) => item.type === "weapon")
.sort((a, b) => a?.sort - b?.sort)
.forEach((item) => {
item.prepareDerivedData();
@ -185,19 +356,43 @@ export class M5Character extends Actor {
item.system.stats.damageBonus +
")";
}
if (item.system.valuable) {
ret.stats.wealth += this.calculateValue(item.system.value * item.system.quantity, item.system.currency);
}
if (item.system.hoarded) {
ret.stats.hoard += this.calculateValue(item.system.value * item.system.quantity, item.system.currency);
}
if (!!item.system.containerId) {
ret.gear.containers[item.system.containerId].weight += item.system.weight;
if (ret.gear.containers[item.system.containerId].equipped) {
ret.stats.encumbrance += item.system.weight;
}
} else if (item.system.equipped) {
ret.stats.encumbrance += item.system.weight || 0;
}
ret.gear.weapons[item.id] = {
label: label,
icon: item.img,
skillId: item.system.skillId,
magic: item.system.magic,
abw: item.system.abw || 0,
valuable: item.system?.valuable,
hoarded: item.system?.hoarded,
value: item.system.value || 0,
currency: item.system.currency || "",
calc: item.system.calc,
special: item.system.special,
damageBase: item.system.damageBase,
equipped: item.system?.equipped,
weight: item.system.weight || 0,
containerId: item.system.containerId || "",
};
});
}
if (!skip?.defensiveWeapons) {
context.items
?.filter((item) => item.type === "defensiveWeapon")
.sort((a, b) => a?.sort - b?.sort)
.forEach((item) => {
item.prepareDerivedData();
@ -205,19 +400,108 @@ export class M5Character extends Actor {
if (item.system.magic) {
label += "*(" + (item.system.stats.defenseBonus < 0 ? "" : "+") + item.system.stats.defenseBonus + ")";
}
if (item.system.valuable) {
ret.stats.wealth += this.calculateValue(item.system.value * item.system.quantity, item.system.currency);
}
if (item.system.hoarded) {
ret.stats.hoard += this.calculateValue(item.system.value * item.system.quantity, item.system.currency);
}
if (!!item.system.containerId) {
ret.gear.containers[item.system.containerId].weight += item.system.weight;
if (ret.gear.containers[item.system.containerId].equipped) {
ret.stats.encumbrance += item.system.weight;
}
} else if (item.system.equipped) {
ret.stats.encumbrance += item.system.weight || 0;
}
ret.gear.defensiveWeapons[item.id] = {
label: label,
icon: item.img,
skillId: item.system.skillId,
magic: item.system.magic,
abw: item.system.abw || 0,
valuable: item.system?.valuable,
hoarded: item.system?.hoarded,
value: item.system.value || 0,
currency: item.system.currency || "",
defenseBonus: item.system.stats.defenseBonus,
calc: item.system.calc,
equipped: item.system?.equipped,
weight: item.system.weight || 0,
containerId: item.system.containerId || "",
};
});
context.items
?.filter((item) => item.type === "armor")
.sort((a, b) => a?.sort - b?.sort)
.forEach((item) => {
item.prepareDerivedData();
let label = item.name;
if (item.system.magic) {
label += "*";
}
if (item.system.valuable) {
ret.stats.wealth += this.calculateValue(item.system.value * item.system.quantity, item.system.currency);
}
if (item.system.hoarded) {
ret.stats.hoard += this.calculateValue(item.system.value * item.system.quantity, item.system.currency);
}
if (!!item.system.containerId) {
ret.gear.containers[item.system.containerId].weight += item.system.weight;
if (ret.gear.containers[item.system.containerId].equipped) {
ret.stats.encumbrance += item.system.weight;
}
} else if (item.system.equipped) {
ret.stats.encumbrance += 0;
} else {
ret.stats.encumbrance += item.system.weight || 0;
}
ret.gear.armor[item.id] = {
label: label,
icon: item.img,
magic: item.system.magic,
abw: item.system.abw || 0,
valuable: item.system?.valuable,
hoarded: item.system?.hoarded,
value: item.system.value || 0,
currency: item.system.currency || "",
lpProtection: item.system.lpProtection,
calc: item.system.calc,
equipped: item.system?.equipped,
weight: item.system.weight || 0,
containerId: item.system.containerId || "",
};
});
}
if (!skip?.armor) {
if (!skip?.class) {
context.items
?.filter((item) => item.type === "armor")
?.filter((item) => item.type === "class")
.sort((a, b) => b?.system.magicUsing - a?.system.magicUsing)
.forEach((item, index) => {
if (index !== 0) {
item.system.equipped = false;
} else {
item.system.equipped = true;
data.info.magicUsing = item.system.magicUsing;
data.lernKostenZauber = item.system.lernKostenZauber;
}
if (typeof data.info.class === "string") {
data.info.class = {};
}
data.info.class[item.id] = item.name;
});
}
if (!skip?.effects) {
context.items
?.filter((item) => item.type === "effect")
.sort((a, b) => a?.sort - b?.sort)
.forEach((item) => {
item.prepareDerivedData();
@ -226,24 +510,73 @@ export class M5Character extends Actor {
label += "*";
}
ret.gear.armor[item.id] = {
ret.gear.effects[item.id] = {
label: label,
icon: item.img,
magic: item.system.magic,
calc: item.system.calc,
equipped: item.system?.equipped || false,
duration: item.system?.duration || { time: 0, unit: "" },
};
});
}
if (!skip?.skills) {
context.items
?.filter((item) => item.type === "skill")
.sort((a, b) => a?.sort - b?.sort)
.forEach((item) => {
item.prepareDerivedData();
const skillMap = ret.skills[item.system.type];
skillMap[item.id] = {
label: item.name,
icon: item.img,
fw: item.system.fw,
attribute: item.system.attribute,
pp: item.system.pp,
calc: item.system.calc,
} as M5SkillCalculated;
});
}
if (!skip?.spells) {
context.items
?.filter((item) => item.type === "spell")
.sort((a, b) => a?.sort - b?.sort)
.forEach((item) => {
item.prepareDerivedData();
ret.spells[item.id] = {
label: item.name,
icon: item.img,
process: "midgard5.spell-process-" + item.system.process,
calc: item.system.calc,
type: item.system.type,
castDuration: item.system.castDuration || 0,
ap: item.system.ap || 0,
range: item.system.range || 0,
effectTarget: item.system.effectTarget,
effectArea: item.system.effectArea,
effectDuration: item.system.effectDuration || 0,
equipped: item.system?.equipped || false,
};
});
}
if (!skip?.kampfkuenste) {
context.items
?.filter((item) => item.type === "kampfkunst")
.sort((a, b) => a?.sort - b?.sort)
.forEach((item) => {
item.prepareDerivedData();
ret.kampfkuenste[item.id] = {
label: item.name,
icon: item.img,
isKido: item.system.isKido,
type: item.system.type,
variante: item.system.variante,
calc: item.system.calc,
};
});
}
@ -251,6 +584,21 @@ export class M5Character extends Actor {
return ret;
}
raceBonus(race: string) {
switch (race) {
case "Elf":
return 2;
case "Gnom":
return 4;
case "Halbling":
return 4;
case "Zwerg":
return 3;
default:
return 0;
}
}
prepareDerivedData() {
console.log("M5Character", "prepareDerivedData");
const data = (this as any).system;
@ -323,7 +671,7 @@ export class M5Character extends Actor {
return data?.attributes[name];
}
createSkill(skillName: string): Promise<M5Item> {
async createSkill(skillName: string): Promise<M5Item> {
const itemData = {
name: skillName,
type: "skill",
@ -335,17 +683,57 @@ export class M5Character extends Actor {
});
}
createItem(itemName: string, itemType: M5ItemType, options?: any): Promise<M5Item> {
const itemData = {
name: itemName,
type: itemType,
data: options,
};
return (this as any).createEmbeddedDocuments("Item", [itemData]).then((docs) => {
const item = docs[0];
return item;
});
}
async createEffect(itemName: string, mods: M5ItemMod[]): Promise<M5Item> {
const itemData = {
name: itemName,
type: "effect",
system: { mods: mods, equipped: true },
};
return (this as any).createEmbeddedDocuments("Item", [itemData]).then((docs) => {
const item = docs[0];
return item;
});
}
getItem(itemId: string): any {
if (!(this as any).items) return null;
return (this as any).getEmbeddedDocument("Item", itemId);
}
private calculateValue(value: number, currency: string): number {
switch (currency) {
case "gold":
return value;
case "silver":
return parseFloat((value / 10).toPrecision(3));
case "copper":
return parseFloat((value / 100).toPrecision(3));
default:
return 0;
}
}
private modResult(value: number): M5ModResult {
return {
value: value,
mods: [
{
item: (game as Game).i18n.localize("ACTOR.TypeCharacter"),
item: (game as Game).i18n.localize("TYPES.Actor.character"),
operation: M5ModOperation.SET,
value: value,
},

View File

@ -1,158 +1,173 @@
import { M5Attribute, M5AttributeCalculated, M5Attributes, M5CharacterCalculatedData, M5ItemMod, M5ModOperation, M5ModResult, M5ModSource, M5ModType, M5Stats, M5ModPair } from "../M5Base"
import { M5Attribute, M5AttributeCalculated, M5Attributes, M5CharacterCalculatedData, M5ItemMod, M5ModOperation, M5ModResult, M5ModSource, M5ModType, M5Stats, M5ModPair } from "../M5Base";
export default class M5ModAggregate {
private attributes = new Map<string, Array<M5ModPair>>()
private stats = new Map<string, Array<M5ModPair>>()
private skills = new Map<string, Array<M5ModPair>>()
private attributes = new Map<string, Array<M5ModPair>>();
private stats = new Map<string, Array<M5ModPair>>();
private skills = new Map<string, Array<M5ModPair>>();
constructor(public data: any, public calc: M5CharacterCalculatedData) {
const characterString = (game as Game).i18n.localize("ACTOR.TypeCharacter")
const characterString = (game as Game).i18n.localize("TYPES.Actor.character");
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.ST, operation: M5ModOperation.SET, value: data.attributes.st.value }, characterString)
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.GS, operation: M5ModOperation.SET, value: data.attributes.gs.value }, characterString)
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.GW, operation: M5ModOperation.SET, value: data.attributes.gw.value }, characterString)
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.KO, operation: M5ModOperation.SET, value: data.attributes.ko.value }, characterString)
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.IN, operation: M5ModOperation.SET, value: data.attributes.in.value }, characterString)
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.ZT, operation: M5ModOperation.SET, value: data.attributes.zt.value }, characterString)
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.AU, operation: M5ModOperation.SET, value: data.attributes.au.value }, characterString)
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.PA, operation: M5ModOperation.SET, value: data.attributes.pa.value }, characterString)
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.WK, operation: M5ModOperation.SET, value: data.attributes.wk.value }, characterString)
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.ST, operation: M5ModOperation.SET, value: data.attributes.st.value }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.GS, operation: M5ModOperation.SET, value: data.attributes.gs.value }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.GW, operation: M5ModOperation.SET, value: data.attributes.gw.value }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.KO, operation: M5ModOperation.SET, value: data.attributes.ko.value }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.IN, operation: M5ModOperation.SET, value: data.attributes.in.value }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.ZT, operation: M5ModOperation.SET, value: data.attributes.zt.value }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.AU, operation: M5ModOperation.SET, value: data.attributes.au.value }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.PA, operation: M5ModOperation.SET, value: data.attributes.pa.value }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.WK, operation: M5ModOperation.SET, value: data.attributes.wk.value }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.ST, operation: M5ModOperation.ADD_100, value: data.attributes.st.bonus }, characterString)
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.GS, operation: M5ModOperation.ADD_100, value: data.attributes.gs.bonus }, characterString)
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.GW, operation: M5ModOperation.ADD_100, value: data.attributes.gw.bonus }, characterString)
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.KO, operation: M5ModOperation.ADD_100, value: data.attributes.ko.bonus }, characterString)
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.IN, operation: M5ModOperation.ADD_100, value: data.attributes.in.bonus }, characterString)
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.ZT, operation: M5ModOperation.ADD_100, value: data.attributes.zt.bonus }, characterString)
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.AU, operation: M5ModOperation.ADD_100, value: data.attributes.au.bonus }, characterString)
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.PA, operation: M5ModOperation.ADD_100, value: data.attributes.pa.bonus }, characterString)
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.WK, operation: M5ModOperation.ADD_100, value: data.attributes.wk.bonus }, characterString)
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.ST, operation: M5ModOperation.ADD_100, value: data.attributes.st.bonus }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.GS, operation: M5ModOperation.ADD_100, value: data.attributes.gs.bonus }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.GW, operation: M5ModOperation.ADD_100, value: data.attributes.gw.bonus }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.KO, operation: M5ModOperation.ADD_100, value: data.attributes.ko.bonus }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.IN, operation: M5ModOperation.ADD_100, value: data.attributes.in.bonus }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.ZT, operation: M5ModOperation.ADD_100, value: data.attributes.zt.bonus }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.AU, operation: M5ModOperation.ADD_100, value: data.attributes.au.bonus }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.PA, operation: M5ModOperation.ADD_100, value: data.attributes.pa.bonus }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.WK, operation: M5ModOperation.ADD_100, value: data.attributes.wk.bonus }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.DEFENSE, operation: M5ModOperation.SET, value: calc.stats.defenseBonus.value }, characterString)
this.push({ type: M5ModType.STAT, id: M5Stats.ATTACK, operation: M5ModOperation.SET, value: calc.stats.attackBonus.value }, characterString)
this.push({ type: M5ModType.STAT, id: M5Stats.DAMAGE, operation: M5ModOperation.SET, value: calc.stats.damageBonus.value }, characterString)
this.push({ type: M5ModType.STAT, id: M5Stats.MOVEMENT, operation: M5ModOperation.SET, value: calc.stats.movementBonus.value }, characterString)
this.push({ type: M5ModType.STAT, id: M5Stats.RESISTANCE_MIND, operation: M5ModOperation.SET, value: calc.stats.resistanceMind.value }, characterString)
this.push({ type: M5ModType.STAT, id: M5Stats.RESISTANCE_BODY, operation: M5ModOperation.SET, value: calc.stats.resistanceBody.value }, characterString)
this.push({ type: M5ModType.STAT, id: M5Stats.SPELL_CASTING, operation: M5ModOperation.SET, value: calc.stats.spellCasting.value }, characterString)
this.push({ type: M5ModType.STAT, id: M5Stats.BRAWL, operation: M5ModOperation.SET, value: calc.stats.brawl.value }, characterString)
this.push({ type: M5ModType.STAT, id: M5Stats.POISON_RESISTANCE, operation: M5ModOperation.SET, value: calc.stats.poisonResistance.value }, characterString)
this.push({ type: M5ModType.STAT, id: M5Stats.LP, operation: M5ModOperation.SET, value: calc.stats.lp.value }, characterString)
this.push({ type: M5ModType.STAT, id: M5Stats.AP, operation: M5ModOperation.SET, value: calc.stats.ap.value }, characterString)
this.push({ type: M5ModType.STAT, id: M5Stats.DEFENSE, operation: M5ModOperation.SET, value: calc.stats.defenseBonus.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.ATTACK, operation: M5ModOperation.SET, value: calc.stats.attackBonus.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.DAMAGE, operation: M5ModOperation.SET, value: calc.stats.damageBonus.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.MOVEMENT, operation: M5ModOperation.SET, value: calc.stats.movement.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.RESISTANCE_MIND, operation: M5ModOperation.SET, value: calc.stats.resistanceMind.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.RESISTANCE_BODY, operation: M5ModOperation.SET, value: calc.stats.resistanceBody.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.SPELL_CASTING, operation: M5ModOperation.SET, value: calc.stats.spellCasting.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.BRAWL, operation: M5ModOperation.SET, value: calc.stats.brawl.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.POISON_RESISTANCE, operation: M5ModOperation.SET, value: calc.stats.poisonResistance.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.LP, operation: M5ModOperation.SET, value: calc.stats.lp.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.AP, operation: M5ModOperation.SET, value: calc.stats.ap.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.PROTECTION_LP, operation: M5ModOperation.SET, value: calc.stats.lpProtection.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.PROTECTION_AP, operation: M5ModOperation.SET, value: calc.stats.apProtection.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.DEPRIVATION_COLD, operation: M5ModOperation.SET, value: calc.stats.deprivationCold.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.DEPRIVATION_HEAT, operation: M5ModOperation.SET, value: calc.stats.deprivationHeat.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.DEPRIVATION_FOOD, operation: M5ModOperation.SET, value: calc.stats.deprivationFood.value }, characterString);
}
push(mod: M5ItemMod, source: string) {
if (!mod?.id || mod.id === "")
return
if (!mod?.id || mod.id === "") return;
let map: Map<string, Array<M5ModPair>> = null
if (mod.type === M5ModType.ATTRIBUTE)
map = this.attributes
else if (mod.type === M5ModType.STAT)
map = this.stats
else if (mod.type === M5ModType.SKILL)
map = this.skills
let map: Map<string, Array<M5ModPair>> = null;
if (mod.type === M5ModType.ATTRIBUTE) map = this.attributes;
else if (mod.type === M5ModType.STAT) map = this.stats;
else if (mod.type === M5ModType.SKILL) map = this.skills;
if (map) {
const pair: M5ModPair = {
mod: mod,
source: source
}
source: source,
};
if (map.has(mod.id))
map.get(mod.id).push(pair)
else
map.set(mod.id, [pair])
if (map.has(mod.id)) map.get(mod.id).push(pair);
else map.set(mod.id, [pair]);
}
}
calculate() {
const calc = this.calc
const calc = this.calc;
this.attributes.forEach((pairs, id) => {
const res = M5ModAggregate.processPairs(pairs)
const res = M5ModAggregate.processPairs(pairs);
calc.attributes[id] = {
value: res.value,
bonus: M5ModAggregate.attributeBonus(res.value),
mods: res.mods
} as M5AttributeCalculated
mods: res.mods,
} as M5AttributeCalculated;
//console.log("calc.attributes." + id, calc.attributes[id])
})
});
this.stats.forEach((pairs, id) => {
const res = M5ModAggregate.processPairs(pairs)
calc.stats[id] = res
})
const res = M5ModAggregate.processPairs(pairs);
calc.stats[id] = res;
});
const ret = {}
const ret = {};
this.skills.forEach((pairs, id) => {
ret[id] = pairs
})
ret[id] = pairs;
});
return ret
return ret;
}
static pairAsSource(pair: M5ModPair): M5ModSource {
return {
operation: pair.mod.operation,
value: pair.mod.value,
item: pair.source
}
item: pair.source,
};
}
static processPairs(arr: Array<M5ModPair>): M5ModResult {
let ret: M5ModResult = {
mods: [],
value: 0
}
value: 0,
};
let mods = arr.filter(pair => pair.mod.operation === M5ModOperation.FIXED).sort((a, b) => b.mod.value - a.mod.value)
let pair = mods.length === 0 ? null : mods[0]
let mods = arr.filter((pair) => pair.mod.operation === M5ModOperation.FIXED).sort((a, b) => b.mod.value - a.mod.value);
let pair = mods.length === 0 ? null : mods[0];
if (pair) {
ret.mods.push(this.pairAsSource(pair))
ret.value = pair.mod.value
ret.mods.push(this.pairAsSource(pair));
ret.value = pair.mod.value;
} else {
mods = arr.filter(pair => pair.mod.operation === M5ModOperation.SET).sort((a, b) => b.mod.value - a.mod.value)
mods = arr.filter((pair) => pair.mod.operation === M5ModOperation.SET).sort((a, b) => b.mod.value - a.mod.value);
if (mods.length !== 0) {
ret.mods.push(this.pairAsSource(mods[0]))
ret.value = mods[0].mod.value
ret.mods.push(this.pairAsSource(mods[0]));
ret.value = mods[0].mod.value;
}
mods = arr.filter(pair => pair.mod.operation === M5ModOperation.ADD_100)
mods = arr.filter((pair) => pair.mod.operation === M5ModOperation.ADD_100);
if (mods.length !== 0) {
ret.mods = ret.mods.concat(mods.map(this.pairAsSource))
const bonus = mods.map(p => p.mod.value).reduce((a, b) => a + b, 0)
ret.value = Math.min(100, Math.max(0, ret.value + bonus))
ret.mods = ret.mods.concat(mods.map(this.pairAsSource));
const bonus = mods.map((p) => p.mod.value).reduce((a, b) => a + b, 0);
ret.value = Math.min(100, Math.max(0, ret.value + bonus));
}
mods = arr.filter(pair => pair.mod.operation === M5ModOperation.ADD)
mods = arr.filter((pair) => pair.mod.operation === M5ModOperation.ADD);
if (mods.length !== 0) {
ret.mods = ret.mods.concat(mods.map(this.pairAsSource))
const bonus = mods.map(p => p.mod.value).reduce((a, b) => a + b, 0)
ret.value = Math.max(0, ret.value + bonus)
ret.mods = ret.mods.concat(mods.map(this.pairAsSource));
const bonus = mods.map((p) => p.mod.value).reduce((a, b) => a + b, 0);
ret.value = Math.max(0, ret.value + bonus);
}
mods = arr.filter((pair) => pair.mod.operation === M5ModOperation.SUBTRACT);
if (mods.length !== 0) {
ret.mods = ret.mods.concat(mods.map(this.pairAsSource));
const bonus = mods.map((p) => p.mod.value).reduce((a, b) => a + b, 0);
ret.value = ret.value - bonus;
}
mods = arr.filter((pair) => pair.mod.operation === M5ModOperation.MULTIPLY);
if (mods.length !== 0) {
ret.mods = ret.mods.concat(mods.map(this.pairAsSource));
const bonus = mods.map((p) => p.mod.value).reduce((a, b) => a * b, 1);
ret.value = Math.max(0, ret.value * bonus);
}
mods = arr.filter((pair) => pair.mod.operation === M5ModOperation.DIVISION);
if (mods.length !== 0) {
ret.mods = ret.mods.concat(mods.map(this.pairAsSource));
const bonus = mods.map((p) => p.mod.value).reduce((a, b) => a * b, 1);
ret.value = Math.max(0, Math.floor(ret.value / bonus));
}
}
return ret
return ret;
}
static attributeMinMax(attribute: M5Attribute) {
return Math.min(100, Math.max(0, attribute.value + attribute.bonus))
return Math.min(100, Math.max(0, attribute.value + attribute.bonus));
}
static attributeBonus(value: number) {
if (value > 95)
return 2
if (value > 80)
return 1
if (value > 20)
return 0
if (value > 5)
return -1
return -2
if (value > 95) return 2;
if (value > 80) return 1;
if (value > 20) return 0;
if (value > 5) return -1;
return -2;
}
//static modToString(mod: M5ItemMod): string { }
}

View File

@ -13,8 +13,24 @@ export class M5Item extends Item {
const character = actor as M5Character;
const itemData = (this as any).system;
const calc = itemData.calc;
const name = (this as any).name;
if (itemType === "skill") {
if (itemType === "item") {
calc.containers = null;
if (actor) {
const actorCalc = actor.derivedData({ containers: false, items: true, spells: true, effects: true, kampfkuenste: true, encumbrance: true, class: true });
if (actorCalc) {
calc.containers = actorCalc.gear.containers;
}
const container = character.getItem(itemData.containerId);
//console.log("M5Item.prepareDerivedData:containers", itemData, container?.system)
if (container) {
container.prepareDerivedData();
const containerData = container.system;
}
}
} else if (itemType === "skill") {
calc.fw = itemData.fw;
calc.bonus = 0;
@ -30,8 +46,40 @@ export class M5Item extends Item {
},
];
// Adjust attribute Aussehen based on Athletik skill
if (name === "Athletik") {
itemData.mods[0] = { type: "attribute", id: "au", operation: "add100", value: Math.floor(calc.fw / 3) };
}
// Adjust stat Bewegungsweite based on Laufen skill
if (name === "Laufen") {
itemData.mods[0] = { type: "stat", id: "movement", operation: "add", value: Math.floor(calc.fw / 3) };
}
// Adjust stat Kälte based on Überleben (Gebirge) skill
if (name === "Überleben (Gebirge)") {
itemData.mods[0] = { type: "stat", id: "deprivationCold", operation: "add", value: Math.floor(calc.fw * 5) };
}
// // Adjust stat Kälte based on Überleben (Steppe) skill
if (name === "Überleben (Steppe)") {
itemData.mods[0] = { type: "stat", id: "deprivationHeat", operation: "add", value: Math.floor(calc.fw * 5) };
}
// // Adjust stat Durst & Hunger based on Robustheit skill
if (name === "Robustheit") {
itemData.mods[0] = { type: "stat", id: "deprivationFood", operation: "add", value: Math.floor(calc.fw * 5) };
}
if (character) {
const actorCalc = character.derivedData({ skills: true, weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true });
const actorCalc = character.derivedData({
containers: true,
skills: true,
items: true,
spells: true,
effects: true,
kampfkuenste: true,
encumbrance: true,
class: true,
});
if (actorCalc?.skillMods && Object.keys(actorCalc.skillMods).indexOf(itemId) !== -1) {
pairs = pairs.concat(actorCalc.skillMods[itemId]);
}
@ -52,7 +100,8 @@ export class M5Item extends Item {
const res = M5ModAggregate.processPairs(pairs);
res.mods.forEach((mod) => {
if ([M5ModOperation.SET, M5ModOperation.FIXED].includes(mod.operation)) calc.fw = mod.value;
else calc.bonus += mod.value;
else if ([M5ModOperation.SUBTRACT].includes(mod.operation)) calc.bonus -= mod.value;
else if ([M5ModOperation.ADD].includes(mod.operation)) calc.bonus += mod.value;
});
calc.ew = calc.fw + calc.bonus;
@ -63,12 +112,20 @@ export class M5Item extends Item {
calc.special = itemData.special ? 2 : 0;
calc.ew = calc.special + itemData.stats.attackBonus;
calc.combatSkills = null;
calc.containers = null;
if (actor) {
const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true });
const actorCalc = character.derivedData({ items: true, spells: true, effects: true, kampfkuenste: true, encumbrance: true, class: true });
if (actorCalc) {
calc.ew += actorCalc.stats.attackBonus.value;
calc.combatSkills = actorCalc.skills.combat;
calc.containers = actorCalc.gear.containers;
}
const container = character.getItem(itemData.containerId);
//console.log("M5Item.prepareDerivedData:containers", itemData, container?.system)
if (container) {
container.prepareDerivedData();
const containerData = container.system;
}
const skill = character.getItem(itemData.skillId);
@ -79,6 +136,9 @@ export class M5Item extends Item {
calc.ew += skillData.calc.ew;
calc.bonus += skillData.calc.bonus;
calc.fw += skillData.fw;
} else {
calc.ew += 4;
calc.fw += 4;
}
}
} else if (itemType === "defensiveWeapon") {
@ -87,12 +147,21 @@ export class M5Item extends Item {
calc.special = itemData.special ? 2 : 0;
calc.ew = calc.special + itemData.stats.defenseBonus;
calc.combatSkills = null;
calc.containers = null;
if (actor) {
const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true });
const actorCalc = character.derivedData({ items: true, spells: true, effects: true, kampfkuenste: true, encumbrance: true, class: true });
if (actorCalc) {
calc.ew += actorCalc.stats.defense.value + actorCalc.stats.defenseBonus.value;
calc.combatSkills = actorCalc.skills.combat;
calc.containers = actorCalc.gear.containers;
}
const container = character.getItem(itemData.containerId);
//console.log("M5Item.prepareDerivedData:containers", itemData, container?.system)
if (container) {
container.prepareDerivedData();
const containerData = container.system;
}
const skill = character.getItem(itemData.skillId);
@ -105,16 +174,67 @@ export class M5Item extends Item {
calc.fw += skillData.fw;
}
}
} else if (itemType === "armor") {
itemData.mods[0] = { type: "stat", id: "defenseBonus", operation: "add", value: itemData.stats.defenseBonus };
itemData.mods[1] = { type: "stat", id: "attackBonus", operation: "add", value: itemData.stats.attackBonus };
itemData.mods[2] = { type: "stat", id: "movement", operation: "add", value: itemData.stats.movementBonus };
itemData.mods[3] = { type: "attribute", id: "gw", operation: "add100", value: itemData.attributeMod.gw };
itemData.mods[4] = { type: "stat", id: "lpProtection", operation: "set", value: itemData.lpProtection };
itemData.mods[5] = { type: "stat", id: "apProtection", operation: "set", value: itemData.apProtection };
calc.containers = null;
if (actor) {
const actorCalc = actor.derivedData({ items: true, spells: true, effects: true, kampfkuenste: true, encumbrance: true, class: true });
if (actorCalc) {
calc.containers = actorCalc.gear.containers;
}
const container = character.getItem(itemData.containerId);
//console.log("M5Item.prepareDerivedData:containers", itemData, container?.system)
if (container) {
container.prepareDerivedData();
const containerData = container.system;
}
}
} else if (itemType === "spell") {
calc.fw = 0;
if (actor) {
const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true });
const actorCalc = character.derivedData({ containers: true, items: true, spells: true, effects: true, kampfkuenste: true, encumbrance: true, class: true });
if (actorCalc) {
calc.ew += actorCalc.stats.spellCasting.value;
calc.ew = actorCalc.stats.spellCasting.value;
}
}
} else if (itemType === "item") {
} else if (itemType === "kampfkunst") {
calc.fw = 0;
calc.bonus = 0;
calc.ew = 0;
calc.generalSkills = null;
if (actor) {
const actorCalc = character.derivedData({ containers: true, items: true, spells: true, effects: true, kampfkuenste: true, encumbrance: true, class: true });
if (actorCalc) {
calc.generalSkills = actorCalc.skills.general;
}
const skill = character.getItem(itemData.skillId);
if (skill) {
skill.prepareDerivedData();
const skillData = skill.system;
calc.ew = skillData.calc.ew;
calc.fw = skillData.fw + calc.bonus;
itemData.rolls.formulas[0].label = skill.name;
}
}
} else if (itemType === "class") {
itemData.mods[0] = { type: "stat", id: "resistanceBody", operation: "add", value: itemData.resistanceBody };
itemData.mods[1] = { type: "stat", id: "resistanceMind", operation: "add", value: itemData.resistanceMind };
}
if (itemData?.mods) {
calc.mods = {};
for (let modKey in itemData.mods) {
if (itemData.mods[modKey].type === M5ModType.SKILL && itemData.mods[modKey].id?.includes("midgard5")) {
itemData.mods[modKey].id = actor?.items.find((x) => x.name === game["i18n"].localize(itemData.mods[modKey].id))?.id;
}
}
Object.keys(itemData?.mods).forEach((key) => {
const mod = itemData.mods[key];
const modCalc = {};
@ -135,7 +255,13 @@ export class M5Item extends Item {
}
case M5ModType.SKILL: {
if (character) {
const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true });
const actorCalc = character.derivedData({
items: true,
spells: true,
effects: true,
kampfkuenste: true,
encumbrance: true,
});
if (actorCalc) {
let category = (game as Game).i18n.localize("midgard5.skill");
Object.keys(actorCalc.skills.general).forEach((skillId) => {
@ -188,7 +314,7 @@ export class M5Item extends Item {
return ret;
}
async roll() {
async roll(toggleAutomatedRoll = false) {
const item = this as any;
// Initialize chat data.
@ -215,8 +341,20 @@ export class M5Item extends Item {
}
});
const roll = new M5Roll(rollData, this.actor, item.name);
return roll.toMessage();
const roll = new M5Roll(rollData, this.actor, item.name, item.id);
if (await roll.toMessage(toggleAutomatedRoll)) {
if (item.type === "spell" || item.type === "kampfkunst") {
if (this.actor["system"].ap.value >= item.system.ap) {
this.actor["update"]({
data: {
ap: {
value: this.actor["system"].ap.value - item.system.ap,
},
},
});
}
}
}
} else {
ChatMessage.create({
speaker: speaker,

View File

@ -1,15 +1,22 @@
import { Evaluated } from "@league-of-foundry-developers/foundry-vtt-types/src/foundry/client/dice/roll";
import { M5Character } from "../actors/M5Character";
import { M5EwResult, M5RollData, M5RollResult, M5SkillUnlearned } from "../M5Base";
import { M5EwResult, M5ModOperation, M5ModType, M5RollData, M5RollResult, M5SkillUnlearned, M5Stats } from "../M5Base";
import { stat } from "fs";
export class M5Roll { // extends Roll<M5RollData>
static readonly TEMPLATE_PATH = "systems/midgard5/templates/chat/roll-m5.hbs"
export class M5Roll {
// extends Roll<M5RollData>
static readonly TEMPLATE_PATH = "systems/midgard5/templates/chat/roll-m5.hbs";
public _evaluated: boolean = false
public _total: number = 0
public pool: PoolTerm = null
public _evaluated: boolean = false;
public _total: number = 0;
public pool: PoolTerm = null;
constructor(public data: M5RollData, public actor: any, public label: string) {
constructor(
public data: M5RollData,
public actor: any,
public label: string,
public id?: string
) {
//super(null)
//this.data = rollData
}
@ -17,229 +24,443 @@ export class M5Roll { // extends Roll<M5RollData>
// @ts-ignore
//override evaluate(options?: InexactPartial<RollTerm.EvaluationOptions>): Evaluated<Roll<M5RollData>> | Promise<Evaluated<Roll<M5RollData>>> {
evaluate() {
const indexMap = new Map<number, string>()
const rollNames = Object.keys(this.data.rolls)
const rolls = rollNames.filter(rollName => this.data.rolls[rollName].enabled).map((rollName, index) => {
indexMap.set(index, rollName)
const formula = this.data.rolls[rollName]
const roll = new Roll(formula.formula, this.data)
return roll
})
this.pool = PoolTerm.fromRolls(rolls)
console.log("evaluate", this._evaluated, this.pool)
return this.pool.evaluate({ async: true }).then(results => {
this._total = 0
const indexMap = new Map<number, string>();
const rollNames = Object.keys(this.data.rolls);
const rolls = rollNames
.filter((rollName) => this.data.rolls[rollName].enabled)
.map((rollName, index) => {
indexMap.set(index, rollName);
const formula = this.data.rolls[rollName];
formula.formula = index === 0 && this.id !== "-1" ? formula.formula + `+ ${this.data.b.modifier}` : formula.formula;
const roll = new Roll(formula.formula, this.data);
return roll;
});
this.pool = PoolTerm.fromRolls(rolls);
console.log("evaluate", this._evaluated, this.pool);
return this.pool.evaluate({ async: true }).then((results) => {
this._total = 0;
results.rolls.forEach((roll, index) => {
const rollIndex = indexMap.get(index)
const rollResult = this.data.rolls[rollIndex] as M5RollResult
const rollIndex = indexMap.get(index);
const rollResult = this.data.rolls[rollIndex] as M5RollResult;
rollResult.result = roll.result
rollResult.total = roll.total
rollResult.totalStr = roll.total.toString()
rollResult.result = roll.result;
rollResult.total = roll.total;
rollResult.totalStr = roll.total.toString();
this._total += roll.total
this._total += roll.total;
let rowRes = M5EwResult.TBD
let face100 = -1
let rowRes = M5EwResult.TBD;
let face100 = -1;
roll.dice.forEach((d, dIndex) => {
rollResult.dice[dIndex.toString()] = d.total
rollResult.dice[dIndex.toString()] = d.total;
if (rowRes === M5EwResult.TBD && dIndex === 0) {
if (d.faces === 20) {
//if (rollResult.type === "ew") {
if (d.total === 1)
rowRes = M5EwResult.FUMBLE
else if (d.total === 20)
rowRes = M5EwResult.CRITICAL
else if (d.total >= 16)
rowRes = M5EwResult.HIGH
if (d.total === 1) rowRes = M5EwResult.FUMBLE;
else if (d.total === 20) rowRes = M5EwResult.CRITICAL;
else if (d.total >= 16) rowRes = M5EwResult.HIGH;
} else if (d.faces === 100) {
face100 = d.total as number
face100 = d.total as number;
}
}
})
});
const parseResult = M5Roll.parseDiceSides(rollResult.formula)
const parseResult = M5Roll.parseDiceSides(rollResult.formula);
//console.log("evaluate roll", parseResult)
if (parseResult?.sides === 20) {
if (roll.total < 20) {
if (rowRes === M5EwResult.TBD || rowRes === M5EwResult.HIGH)
rowRes = M5EwResult.FAIL
if (roll.total < this.data.b.difficulty) {
if (rowRes === M5EwResult.TBD || rowRes === M5EwResult.HIGH) rowRes = M5EwResult.FAIL;
} else {
if (rowRes === M5EwResult.TBD)
rowRes = M5EwResult.PASS
if (rowRes === M5EwResult.TBD) rowRes = M5EwResult.PASS;
}
} else if (face100 >= 0) {
const threshold100 = roll.total + face100
const threshold = Math.floor(threshold100 / 10)
const threshold100 = roll.total + face100;
const threshold = Math.floor(threshold100 / 10);
if (face100 === 100) {
if (rowRes === M5EwResult.TBD)
rowRes = M5EwResult.FUMBLE
if (rowRes === M5EwResult.TBD) rowRes = M5EwResult.FUMBLE;
} else if (roll.total < 0) {
if (rowRes === M5EwResult.TBD)
rowRes = M5EwResult.FAIL
if (rowRes === M5EwResult.TBD) rowRes = M5EwResult.FAIL;
} else if (face100 <= threshold) {
if (rowRes === M5EwResult.TBD)
rowRes = M5EwResult.CRITICAL
if (rowRes === M5EwResult.TBD) rowRes = M5EwResult.CRITICAL;
} else {
if (rowRes === M5EwResult.TBD)
rowRes = M5EwResult.PASS
if (rowRes === M5EwResult.TBD) rowRes = M5EwResult.PASS;
}
}
rollResult.css = rowRes
})
rollResult.css = rowRes;
});
this.data.res.label = this.label
this.data.res.label = this.label;
if ((game as Game).settings.get("midgard5", "automatedPP") && this.data.iType !== null) {
if ((this.data.i.type === "language" || this.data.i.type === "general") && this.data.rolls[0].dice[0] >= 16) {
ui.notifications.notify(`Praxispunkt eingetragen für ${this.actor.items.get(this.id).name}`);
this.actor.items.get(this.id).update({
system: {
pp: this.data.i.pp + 1,
},
});
} else if (this.data.rolls[0].dice[0] === 20) {
if (this.data.i.type === "combat") {
ui.notifications.notify(`Praxispunkt eingetragen für ${this.actor.items.get(this.id).name}`);
// Rolling through skill
this.actor.items.get(this.id).update({
system: {
pp: this.data.i.pp + 1,
},
});
} else if (this.data.iType === "weapon") {
ui.notifications.notify(`Praxispunkt eingetragen für ${this.actor.items.get(this.id).name}`);
// Rolling through Weapon Item
const skill = this.actor.items.get(this.data.i.skillId);
skill.update({
system: {
pp: skill.system.pp + 1,
},
});
} else if (this.data.iType === "defensiveWeapon") {
ui.notifications.notify(`Praxispunkt eingetragen für ${this.actor.items.get(this.id).name}`);
// Rolling through defensiveWeapon Item
const skill = this.actor.items.get(this.data.i.skillId);
skill.update({
system: {
pp: skill.system.pp + 1,
},
});
} else if (this.data.iType === "spell") {
ui.notifications.notify(`Praxispunkt eingetragen für ${this.data.i.process}`);
// Rolling through Spell Item
const klasse = this.actor.items.find((x) => x.type === "class" && x.system.equipped);
klasse.update({
system: {
lernKostenZauber: {
[this.data.i.process]: { pp: klasse.system.lernKostenZauber[this.data.i.process].pp + 1 },
},
},
});
}
}
}
this._evaluated = true
return this
})
this._evaluated = true;
return this;
});
}
async render(): Promise<string> {
return renderTemplate(M5Roll.TEMPLATE_PATH, this.data)
return renderTemplate(M5Roll.TEMPLATE_PATH, this.data);
}
async toMessage() {
if (!this._evaluated)
await this.evaluate()
async toMessage(toggleAutomatedRoll = false) {
let automatedRoll = (game as Game).settings.get("midgard5", "automatedRoll");
automatedRoll = toggleAutomatedRoll ? !automatedRoll : automatedRoll;
let rMode = (game as Game).settings.get("core", "rollMode");
const rMode = (game as Game).settings.get("core", "rollMode")
if (!automatedRoll) {
let checkOptions = await this.popUp({ isPW: this.data.rolls[0].label === (game as Game).i18n.localize("midgard5.pw") });
if (checkOptions["cancelled"]) {
return;
} else {
rMode = checkOptions["rollMode"];
this.data.b = checkOptions;
}
} else {
this.data.b = { difficulty: 20, modifier: 0 };
}
if (!this._evaluated) await this.evaluate();
const faces = this.pool.dice.map((x) => x.faces);
const chatData = {
type: CONST.CHAT_MESSAGE_TYPES.ROLL,
content: await this.render(),
speaker: ChatMessage.getSpeaker({ actor: this.actor }),
sound: CONFIG.sounds.dice,
roll: Roll.fromTerms([this.pool])
}
roll: Roll.fromTerms([this.pool]),
flags: { data: this.data, rerolled: false, faces: faces },
};
ChatMessage.applyRollMode(chatData, rMode)
return ChatMessage.create(chatData)
}
static fromAttribute(actor: any, attributeKey: string) {
const character = actor as M5Character
const attribute = character.attribute(attributeKey)
const rollData = actor.getRollData() as M5RollData
rollData.i = attribute.value + attribute.bonus
rollData.rolls["0"] = {
formula: "@i - 1d100",
enabled: true,
label: (game as Game).i18n.localize("midgard5.pw"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: ""
} as M5RollResult
return new M5Roll(rollData, actor, (game as Game).i18n.localize(`midgard5.actor-${attributeKey}-long`))
let foo = ChatMessage.applyRollMode(chatData, rMode);
return ChatMessage.implementation["create"](foo, { rollMode: rMode });
}
static fromAttributeValue(actor: any, attributeKey: string, attributeValue: number) {
const rollData = actor.getRollData() as M5RollData
rollData.i = attributeValue
const rollData = actor.getRollData() as M5RollData;
const itemData = actor.items.filter((x) => x.type === "effect").map((y) => y.system.mods);
rollData.c = 0;
for (let effectKey in itemData) {
for (let modkey in itemData[effectKey])
if (itemData[effectKey][modkey].type === M5ModType.ATTRIBUTE && itemData[effectKey][modkey].operation === M5ModOperation.ROLL) {
rollData.c += itemData[effectKey][modkey].value;
}
}
rollData.i = attributeValue;
rollData.rolls["0"] = {
formula: "@i - 1d100",
formula: "@i - 1d100 - @c",
enabled: true,
label: (game as Game).i18n.localize("midgard5.pw"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: ""
} as M5RollResult
css: "",
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize(`midgard5.actor-${attributeKey}-long`))
return new M5Roll(rollData, actor, (game as Game).i18n.localize(`midgard5.actor-${attributeKey}-long`));
}
static fromUnlearnedSkill(actor: any, skill: M5SkillUnlearned, skillName: string) {
const rollData = actor.getRollData() as M5RollData
const rollData = actor.getRollData() as M5RollData;
rollData.i = {
fw: skill.fw,
bonus: actor.system.calc?.attributes[skill.attribute]?.bonus ?? 0
}
rollData.iType = "skill"
bonus: actor.system.calc?.attributes[skill.attribute]?.bonus ?? 0,
};
rollData.iType = "skill";
rollData.rolls["0"] = {
formula: "1d20 + @i.fw + @i.bonus",
enabled: true,
label: (game as Game).i18n.localize("midgard5.pw"),
label: (game as Game).i18n.localize("midgard5.ew"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: ""
} as M5RollResult
css: "",
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize(`midgard5.${skillName}`))
return new M5Roll(rollData, actor, (game as Game).i18n.localize(`midgard5.${skillName}`));
}
static brawl(actor: any) {
const rollData = actor.getRollData() as M5RollData
const rollData = actor.getRollData() as M5RollData;
rollData.i = {
attackBonus: 0,
damageBonus: 0
}
damageBonus: 0,
};
rollData.rolls["0"] = {
formula: "1d20 + @c.calc.stats.brawl + @c.calc.stats.attackBonus + @i.attackBonus",
formula: "1d20 + @c.calc.stats.brawlFw",
enabled: true,
label: (game as Game).i18n.localize("midgard5.attack"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: ""
} as M5RollResult
css: "",
} as M5RollResult;
rollData.rolls["1"] = {
formula: "1d6 - 4 + @c.calc.stats.damageBonus + @i.damageBonus",
formula: "1d6 - 4 + @c.calc.stats.damageBonus.value",
enabled: true,
label: (game as Game).i18n.localize("midgard5.damage"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: ""
} as M5RollResult
css: "",
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize("midgard5.brawl"))
return new M5Roll(rollData, actor, (game as Game).i18n.localize("midgard5.brawl"));
}
static deprivationCold(actor: any) {
const rollData = actor.getRollData() as M5RollData;
rollData.rolls["0"] = {
formula: "@c.calc.stats.deprivationCold.value -1D100",
enabled: true,
label: (game as Game).i18n.localize("midgard5.deprivationCold"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: "",
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize("midgard5.deprivationCold"));
}
static deprivationHeat(actor: any) {
const rollData = actor.getRollData() as M5RollData;
rollData.rolls["0"] = {
formula: "@c.calc.stats.deprivationHeat.value -1D100",
enabled: true,
label: (game as Game).i18n.localize("midgard5.deprivationHeat"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: "",
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize("midgard5.deprivationHeat"));
}
static deprivationFood(actor: any) {
const rollData = actor.getRollData() as M5RollData;
rollData.rolls["0"] = {
formula: "@c.calc.stats.deprivationFood.value -1D100",
enabled: true,
label: (game as Game).i18n.localize("midgard5.deprivationFood"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: "",
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize("midgard5.deprivationFood"));
}
static cleanSpell(actor: any) {
const rollData = actor.getRollData() as M5RollData;
rollData.rolls["0"] = {
formula: "1d20 + @c.calc.stats.spellCasting.value",
enabled: true,
label: (game as Game).i18n.localize("midgard5.spellCasting"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: "",
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize("midgard5.spellCasting"));
}
static defense(actor: any) {
const rollData = actor.getRollData() as M5RollData;
rollData.i = {
defenseBonus: 0,
};
rollData.rolls["0"] = {
formula: "1d20 + @c.calc.stats.defense.value + @c.calc.stats.defenseBonus.value",
enabled: true,
label: (game as Game).i18n.localize("midgard5.defense"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: "",
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize("midgard5.defense"));
}
static resistanceMind(actor: any) {
const rollData = actor.getRollData() as M5RollData;
rollData.i = {
defenseBonus: 0,
};
rollData.rolls["0"] = {
formula: "1d20 + @c.calc.stats.resistanceMind.value",
enabled: true,
label: (game as Game).i18n.localize("midgard5.resistanceMind"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: "",
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize("midgard5.resistanceMind"));
}
static resistanceBody(actor: any) {
const rollData = actor.getRollData() as M5RollData;
rollData.i = {
defenseBonus: 0,
};
rollData.rolls["0"] = {
formula: "1d20 + @c.calc.stats.resistanceBody.value",
enabled: true,
label: (game as Game).i18n.localize("midgard5.resistanceBody"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: "",
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize("midgard5.resistanceBody"));
}
static parseDiceSides(formula: string): FormulaParseResult {
const ewMatcher: RegExp = /\d*[dD]20/g
const pwMatcher: RegExp = /(\d+)\s*\-\s*\d*[dD]100/g
const ewMatcher: RegExp = /\d*[dD]20/g;
const pwMatcher: RegExp = /(\d+)\s*\-\s*\d*[dD]100/g;
let res = formula.match(ewMatcher)
let res = formula.match(ewMatcher);
if (res && !!res[0]) {
return {
sides: 20,
type: "ew",
threshold: null
}
threshold: null,
};
}
res = formula.match(pwMatcher)
res = formula.match(pwMatcher);
if (res && !!res[1]) {
return {
sides: 100,
type: "pw",
threshold: parseInt(res[1])
}
threshold: parseInt(res[1]),
};
}
return null
return null;
}
async popUp({
useFortune = false,
difficulty = 20,
modifier = 0,
rollModes = CONFIG.Dice.rollModes,
rollMode = "",
template = "systems/midgard5/templates/chat/task-check-dialog.hbs",
isPW = false,
} = {}) {
const html = await renderTemplate(template, { useFortune, difficulty, modifier, rollModes, rollMode, isPW });
return new Promise((resolve) => {
const data = {
title: (game as Game).i18n.localize("midgard5.chat.roll"),
content: html,
buttons: {
roll: {
label: (game as Game).i18n.localize("midgard5.chat.roll"),
callback: (html) => resolve(this._processTaskCheckOptions(html[0].querySelector("form"))),
},
cancel: {
label: (game as Game).i18n.localize("midgard5.chat.cancel"),
callback: (html) => resolve({ cancelled: true }),
},
},
default: "roll",
close: () => resolve({ cancelled: true }),
};
new Dialog(data, null).render(true);
});
}
_processTaskCheckOptions(form) {
return {
difficulty: parseInt(form.difficulty?.value),
modifier: parseInt(form.modifier?.value),
rollMode: form.rollMode?.value,
};
}
}
interface FormulaParseResult {
sides: number,
type: string,
threshold: number
sides: number;
type: string;
threshold: number;
}

View File

@ -0,0 +1,108 @@
import { M5RollData, M5RollResult } from "../M5Base";
import { M5Roll } from "./M5Roll";
export const reroll = async (roll) => {
const message = (game as Game).messages.get(roll.attr("data-message-id"));
const actor = (game as Game).actors.get(message["speaker"].actor);
const template = "systems/midgard5/templates/chat/reroll-dialog.hbs";
const html = await renderTemplate(template, { sg: actor.system.sg, gp: actor.system.gp });
// Button defining
let buttons = {};
buttons = {
destiny: {
icon: '<i class="fas fa-rotate-left"></i>',
label: (game as Game).i18n.localize("midgard5.chat.destiny"),
callback: () => rerollDie("destiny", "sg"),
},
luckPoints: {
icon: '<i class="fas fa-rotate-left"></i>',
label: (game as Game).i18n.localize("midgard5.chat.luckPoint"),
callback: () => rerollDie("luckPoint", "gp"),
},
modify: {
icon: '<i class="fas fa-plus"></i>',
label: (game as Game).i18n.localize("midgard5.chat.modify") + " +" + (message["flags"].faces[0] === 100 ? 10 : 2),
callback: () => rerollDie("modify", "gp"),
},
cancel: {
icon: '<i class="fas fa-times"></i>',
label: (game as Game).i18n.localize("midgard5.chat.cancel"),
},
};
// Dialog object
new Dialog(
{
title: (game as Game).i18n.localize("midgard5.chat.reroll"),
content: html,
buttons,
render: function () {},
default: "luckPoints",
},
{
classes: ["midgard5"],
}
).render(true);
async function rerollDie(type, target) {
// Update the "content" field
let rollData = actor.getRollData() as M5RollData;
const flagData = message["flags"].data;
rollData.c = flagData.c;
rollData.i = flagData.i;
rollData.b = flagData.b;
rollData.iType = flagData.iType;
rollData.res.label = flagData.res.label + " (" + (game as Game).i18n.localize(`midgard5.chat.${type}`) + ")";
actor.update({
system: {
[target]: actor.system[target] - 1,
},
});
if (type !== "modify") {
for (var key in flagData.rolls) {
if (!!flagData.rolls[key]) {
rollData.rolls[key] = {
formula: flagData.rolls[key]?.formula,
enabled: flagData.rolls[key]?.enabled,
label: flagData.rolls[key]?.label,
result: "",
total: 0,
totalStr: "",
dice: {},
css: "",
} as M5RollResult;
}
}
} else {
for (var key in flagData.rolls) {
if (!!flagData.rolls[key]) {
rollData.rolls[key] = {
formula: key === "0" ? flagData.rolls[key]?.result + " + " + (message["flags"].faces[0] === 100 ? 10 : 2) : flagData.rolls[key]?.result,
enabled: flagData.rolls[key]?.enabled,
label: flagData.rolls[key]?.label,
result: "",
total: 0,
totalStr: "",
dice: {},
css: "",
} as M5RollResult;
}
}
}
const newRoll = new M5Roll(rollData, actor, rollData.res.label, "-1");
if (!newRoll._evaluated) await newRoll.evaluate();
const chatData = {
type: CONST.CHAT_MESSAGE_TYPES.ROLL,
content: await newRoll.render(),
speaker: ChatMessage.getSpeaker({ actor: actor }),
sound: CONFIG.sounds.dice,
roll: Roll.fromTerms([newRoll.pool]),
flags: { rerolled: true },
};
message.update(chatData);
}
};

View File

@ -1,21 +1,34 @@
import Logger from "../../utils/Logger";
import { M5Character } from "../actors/M5Character";
import { M5Item } from "../items/M5Item";
import { M5SkillLearned, M5SkillUnlearned } from "../M5Base";
import { M5ItemType, M5SkillLearned, M5SkillType, M5SkillUnlearned } from "../M5Base";
import { M5Roll } from "../rolls/M5Roll";
export default class M5CharacterSheet extends ActorSheet {
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
template: "systems/midgard5/templates/sheets/character/main.hbs",
width: 800,
width: 1000,
height: 800,
classes: ["midgard5", "sheet", "character"],
tabs: [{ navSelector: ".sheet-navigation", contentSelector: ".sheet-content", initial: "base_values" }],
tabs: [
{
navSelector: ".sheet-navigation",
contentSelector: ".sheet-content",
initial: "base_values",
},
],
});
}
// get template() {
get template() {
//console.log("M5CharacterSheet", this.actor.data.type)
if (this.actor.type === "npc") {
return "systems/midgard5/templates/sheets/npc/main.hbs";
}
else {
return "systems/midgard5/templates/sheets/character/main.hbs";
}
}
// return "systems/midgard5/templates/character_sheet/main.hbs"
// }Options extends ActorSheet.Options = ActorSheet.Options, Data extends object = ActorSheet.Data<Options>
@ -68,28 +81,17 @@ export default class M5CharacterSheet extends ActorSheet {
});
html.find(".roll-attribute-button").on("click", async (event) => {
let elem = event.target;
let attributeStr = elem.dataset["attribute"];
while (!attributeStr) {
elem = elem.parentElement;
if (!elem) return;
attributeStr = elem.dataset["attribute"];
}
const attributeValue = parseInt(elem.dataset["value"]);
let target = event.target.closest("[data-attribute]") as HTMLElement;
let attributeValue = target ? parseInt(target.dataset.value) : null;
let attributeStr = target ? target.dataset.attribute : null;
const roll = M5Roll.fromAttributeValue(this.actor, attributeStr, attributeValue);
//console.log("roll-attribute-button", parent, attributeStr, attributeValue, roll)
await roll.toMessage();
let toggleAutomatedRoll = (event.shiftKey)
await roll.toMessage(toggleAutomatedRoll);
});
html.find(".edit-item").on("click", async (event) => {
let row = event.target.parentElement;
let itemId = row.dataset["item"];
while (!itemId) {
row = row.parentElement;
if (!row) return;
itemId = row.dataset["item"];
}
let target = event.target.closest("[data-item-id]") as HTMLElement;
let itemId = target ? target.dataset.itemId : null;
const context = this.actor as any;
const item = context.items.get(itemId);
@ -97,14 +99,61 @@ export default class M5CharacterSheet extends ActorSheet {
item.sheet.render(true);
});
html.find(".item-delete").on("click", async (event) => {
let row = event.target.parentElement;
let itemId = row.dataset["item"];
while (!itemId) {
row = row.parentElement;
if (!row) return;
itemId = row.dataset["item"];
html.find(".quantity-increase").on("click", async (event) => {
let target = event.target.closest("[data-item-id]") as HTMLElement;
let itemId = target ? target.dataset.itemId : null;
const context = this.actor as any;
const item = context.items.get(itemId);
if (!item.system.quantity) {
item.system.quantity = 0;
}
item.update({
data: {
quantity: item.system.quantity + 1,
},
});
this.render();
});
html.find(".quantity-decrease").on("click", async (event) => {
let target = event.target.closest("[data-item-id]") as HTMLElement;
let itemId = target ? target.dataset.itemId : null;
const context = this.actor as any;
const item = context.items.get(itemId);
if (item.system.quantity > 0) {
item.update({
data: {
quantity: item.system.quantity - 1,
},
});
}
this.render();
});
html.find(".roll-consumable-item").on("click", async (event) => {
let target = event.target.closest("[data-item-id]") as HTMLElement;
let itemId = target ? target.dataset.itemId : null;
const context = this.actor as any;
const item = context.items.get(itemId);
if (item.system.quantity > 0) {
item.update({
data: {
quantity: item.system.quantity - 1,
},
});
}
let toggleAutomatedRoll = (event.shiftKey)
await item.roll(toggleAutomatedRoll);
this.render();
});
html.find(".item-delete").on("click", async (event) => {
let target = event.target.closest("[data-item-id]") as HTMLElement;
let itemId = target ? target.dataset.itemId : null;
const context = this.actor as any;
const item = context.items.get(itemId);
@ -113,28 +162,30 @@ export default class M5CharacterSheet extends ActorSheet {
});
html.find(".roll-learned-button").on("click", async (event) => {
const row = event.target.parentElement.parentElement;
let skillId = row.dataset["item"];
let target = event.target.closest("[data-item-id]") as HTMLElement;
let skillId = target ? target.dataset.itemId : null;
const actor = this.actor as any;
const item = actor.items.get(skillId) as M5Item;
await item.roll();
let toggleAutomatedRoll = (event.shiftKey)
await item.roll(toggleAutomatedRoll);
});
html.find(".roll-general-button").on("click", async (event) => {
const row = event.target.parentElement.parentElement;
let skillName = row.dataset["skill"];
let target = event.target.closest("[data-skill]") as HTMLElement;
let skillName = target ? target.dataset.skill : null;
const data = this.actor.system;
const unlearnedSkill = data.skills.general[skillName] as M5SkillUnlearned;
const roll = M5Roll.fromUnlearnedSkill(this.actor, unlearnedSkill, skillName);
await roll.toMessage();
let toggleAutomatedRoll = (event.shiftKey)
await roll.toMessage(toggleAutomatedRoll);
});
html.find(".learn-button").on("click", async (event) => {
const row = event.target.parentElement.parentElement;
let skillName = row.dataset["skill"];
let target = event.target.closest("[data-skill]") as HTMLElement;
let skillName = target ? target.dataset.skill : null;
const data = this.actor.system;
const unlearnedSkill = data.skills.general[skillName] as M5SkillUnlearned;
@ -153,26 +204,314 @@ export default class M5CharacterSheet extends ActorSheet {
});
});
html.find(".pp-increase").on("click", async (event) => {
let target = event.target.closest("[data-pp-name]") as HTMLElement;
let ppName = target ? target.dataset.ppName : null;
const context = this.actor as any;
const item = context.items.find((x) => x.type === "class" && x.system.equipped);
item.update({
system: {
lernKostenZauber: {
[ppName]: { pp: context.system.lernKostenZauber[ppName].pp + 1 },
},
},
});
this.render();
});
html.find(".pp-decrease").on("click", async (event) => {
let target = event.target.closest("[data-pp-name]") as HTMLElement;
let ppName = target ? target.dataset.ppName : null;
const context = this.actor as any;
const item = context.items.find((x) => x.type === "class" && x.system.equipped);
item.update({
system: {
lernKostenZauber: {
[ppName]: { pp: context.system.lernKostenZauber[ppName].pp - 1 },
},
},
});
this.render();
});
html.find(".fw-increase").on("click", async (event) => {
let target = event.target.closest("[data-item-id]") as HTMLElement;
let itemId = target ? target.dataset.itemId : null;
const context = this.actor as any;
const item = context.items.get(itemId);
if (!item.system.fw) {
item.system.fw = 0;
}
if (item.system.fw < 18) {
item.update({
data: {
fw: Math.min(item.system.fw + 1, 18),
},
});
}
this.render();
});
html.find(".fw-decrease").on("click", async (event) => {
let target = event.target.closest("[data-item-id]") as HTMLElement;
let itemId = target ? target.dataset.itemId : null;
const context = this.actor as any;
const item = context.items.get(itemId);
if (!item.system.fw) {
item.system.fw = 0;
}
if (item.system.fw > 8) {
item.update({
data: {
fw: Math.max(item.system.fw - 1, 8),
},
});
}
this.render();
});
html.find(".roll-weapon-button").on("click", async (event) => {
const row = event.target.parentElement.parentElement;
let itemId = row.dataset["item"];
let target = event.target.closest("[data-item-id]") as HTMLElement;
let itemId = target ? target.dataset.itemId : null;
const context = this.actor as any;
const item = context.items.get(itemId) as M5Item;
await item.roll();
let toggleAutomatedRoll = (event.shiftKey)
await item.roll(toggleAutomatedRoll);
this.render();
});
html.find(".roll-brawl-button").on("click", async (event) => {
const roll = M5Roll.brawl(this.actor);
await roll.toMessage();
let toggleAutomatedRoll = (event.shiftKey)
await roll.toMessage(toggleAutomatedRoll);
});
html.find(".roll-cleanSpell-button").on("click", async (event) => {
const roll = M5Roll.cleanSpell(this.actor);
let toggleAutomatedRoll = (event.shiftKey)
await roll.toMessage(toggleAutomatedRoll);
});
html.find(".roll-deprivationCold-button").on("click", async (event) => {
const roll = M5Roll.deprivationCold(this.actor);
let toggleAutomatedRoll = (event.shiftKey)
await roll.toMessage(toggleAutomatedRoll);
});
html.find(".roll-deprivationHeat-button").on("click", async (event) => {
const roll = M5Roll.deprivationHeat(this.actor);
let toggleAutomatedRoll = (event.shiftKey)
await roll.toMessage(toggleAutomatedRoll);
});
html.find(".roll-deprivationFood-button").on("click", async (event) => {
const roll = M5Roll.deprivationFood(this.actor);
let toggleAutomatedRoll = (event.shiftKey)
await roll.toMessage(toggleAutomatedRoll);
});
html.find(".roll-defense-button").on("click", async (event) => {
const roll = M5Roll.defense(this.actor);
let toggleAutomatedRoll = (event.shiftKey)
await roll.toMessage(toggleAutomatedRoll);
});
html.find(".roll-resistanceMind-button").on("click", async (event) => {
const roll = M5Roll.resistanceMind(this.actor);
let toggleAutomatedRoll = (event.shiftKey)
await roll.toMessage(toggleAutomatedRoll);
});
html.find(".roll-resistanceBody-button").on("click", async (event) => {
const roll = M5Roll.resistanceBody(this.actor);
let toggleAutomatedRoll = (event.shiftKey)
await roll.toMessage(toggleAutomatedRoll);
});
html.find(".change-equipped").on("click", async (event) => {
let target = event.target.closest("[data-item-id]") as HTMLElement;
let itemId = target ? target.dataset.itemId : null;
const context = this.actor as any;
const item = context.items.get(itemId);
item.update({
data: {
equipped: !item.system.equipped,
},
});
this.render();
});
html.find(".add-item").on("click", async (event) => {
const data = this.actor.system;
const character = this.actor as M5Character;
character.createItem((game as Game).i18n.localize("TYPES.Item.item"), M5ItemType.ITEM, { quantity: 1 });
});
html.find(".add-weapon").on("click", async (event) => {
const data = this.actor.system;
const character = this.actor as M5Character;
character.createItem((game as Game).i18n.localize("TYPES.Item.weapon"), M5ItemType.WEAPON);
});
html.find(".add-defensiveWeapon").on("click", async (event) => {
const data = this.actor.system;
const character = this.actor as M5Character;
character.createItem((game as Game).i18n.localize("TYPES.Item.defensiveWeapon"), M5ItemType.DEFENSIVE_WEAPON);
});
html.find(".add-armor").on("click", async (event) => {
const data = this.actor.system;
const character = this.actor as M5Character;
character.createItem((game as Game).i18n.localize("TYPES.Item.armor"), M5ItemType.ARMOR);
});
html.find(".add-container").on("click", async (event) => {
const data = this.actor.system;
const character = this.actor as M5Character;
character.createItem((game as Game).i18n.localize("TYPES.Item.container"), M5ItemType.CONTAINER, { quantity: 1 });
});
html.find(".add-innate-skill").on("click", async (event) => {
const data = this.actor.system;
const character = this.actor as M5Character;
character.createItem((game as Game).i18n.localize("midgard5.innate-ability"), M5ItemType.SKILL, {
type: M5SkillType.INNATE,
});
});
html.find(".add-general-skill").on("click", async (event) => {
const data = this.actor.system;
const character = this.actor as M5Character;
character.createItem((game as Game).i18n.localize("TYPES.Item.skill"), M5ItemType.SKILL, {
type: M5SkillType.GENERAL,
});
});
html.find(".add-combat-skill").on("click", async (event) => {
const data = this.actor.system;
const character = this.actor as M5Character;
character.createItem((game as Game).i18n.localize("midgard5.weapon-skill"), M5ItemType.SKILL, {
type: M5SkillType.COMBAT,
});
});
html.find(".add-language-skill").on("click", async (event) => {
const data = this.actor.system;
const character = this.actor as M5Character;
character.createItem((game as Game).i18n.localize("midgard5.language"), M5ItemType.SKILL, {
type: M5SkillType.LANGUAGE,
});
});
html.find(".add-spell").on("click", async (event) => {
const data = this.actor.system;
const character = this.actor as M5Character;
character.createItem((game as Game).i18n.localize("TYPES.Item.spell"), M5ItemType.SPELL, { process: "none" });
});
html.find(".add-kampfkunst").on("click", async (event) => {
const data = this.actor.system;
const character = this.actor as M5Character;
character.createItem((game as Game).i18n.localize("TYPES.Item.kampfkunst"), M5ItemType.KAMPFKUNST, {
type: "angriff",
variante: "anstuermen",
});
});
html.find(".add-effect").on("click", async (event) => {
const data = this.actor.system;
const character = this.actor as M5Character;
character.createItem((game as Game).i18n.localize("TYPES.Item.effect"), M5ItemType.EFFECT);
});
html.find(".join-combat").on("click", async (event) => {
if (!!game["combat"]) {
let combatant = game["combat"].getCombatantByActor(this.actor._id);
if (!combatant) {
await game["combat"].createEmbeddedDocuments("Combatant", [{ actorId: this.actor._id }]);
combatant = game["combat"].getCombatantByActor(this.actor._id);
}
const initiatives = {
_id: combatant._id,
initiative: this.actor.system.calc.attributes.gw.value,
};
await game["combat"].updateEmbeddedDocuments("Combatant", [initiatives]);
}
});
html.find(".ranged-combat").on("click", async (event) => {
if (!!game["combat"]) {
let combatant = game["combat"].getCombatantByActor(this.actor._id);
if (!combatant) {
await game["combat"].createEmbeddedDocuments("Combatant", [{ actorId: this.actor._id }]);
combatant = game["combat"].getCombatantByActor(this.actor._id);
}
const initiatives = {
_id: combatant._id,
initiative: 0.01 * this.actor.system.calc.attributes.gw.value,
};
await game["combat"].updateEmbeddedDocuments("Combatant", [initiatives]);
}
});
html.find(".spell-combat").on("click", async (event) => {
if (!!game["combat"]) {
let combatant = game["combat"].getCombatantByActor(this.actor._id);
if (!combatant) {
await game["combat"].createEmbeddedDocuments("Combatant", [{ actorId: this.actor._id }]);
combatant = game["combat"].getCombatantByActor(this.actor._id);
}
const initiatives = {
_id: combatant._id,
initiative: 0.001 * this.actor.system.calc.attributes.gw.value,
};
await game["combat"].updateEmbeddedDocuments("Combatant", [initiatives]);
}
});
html.find(".class-item-edit").on("click", async (event) => {
this.actor.items.find((x) => x.type === "class").sheet.render(true);
});
html.find(".class-item-delete").on("click", async (event) => {
this.actor.items.find((x) => x.type === "class").delete();
});
// Drag & Drop
const dragDrop = new DragDrop({
dragSelector: ".items-list .item",
dropSelector: ".sheet-body",
permissions: { dragstart: this._canDragStart.bind(this), drop: this._canDragDrop.bind(this) },
callbacks: { dragstart: this._onTransferItemDragStart.bind(this), drop: this._onTransferItemDrop.bind(this) },
dropSelector: null,
permissions: {
dragstart: this._canDragStart.bind(this),
drop: this._canDragDrop.bind(this),
},
callbacks: {
dragstart: this._onTransferItemDragStart.bind(this),
drop: this._onTransferItemDrop.bind(this),
},
});
dragDrop.bind(html[0]);
}
@ -182,16 +521,14 @@ export default class M5CharacterSheet extends ActorSheet {
}
_canDragDrop(selector) {
return true;
return this.options.editable;
}
_onTransferItemDragStart(event) {
const li = event.currentTarget;
$(event.currentTarget).attr("data-item-actorid", this.actor.id);
const li = event.target;
$(event.target).attr("data-item-actorid", this.actor.id);
const item = this.actor.items.get(li.dataset.itemId);
// limit transfer on personal weapons/armour/gear
if (["skill", "item", "weapon", "defensiveWeapon", "armor", "spell"].includes(item.type)) {
const dragData = {
type: "Transfer",
actorId: this.actor.id,
@ -202,9 +539,6 @@ export default class M5CharacterSheet extends ActorSheet {
if (this.actor.isToken) dragData.tokenId = this.actor.token.id;
event.dataTransfer.setData("text/plain", JSON.stringify(dragData));
} else {
return false;
}
}
async _onTransferItemDrop(event) {
@ -212,6 +546,11 @@ export default class M5CharacterSheet extends ActorSheet {
let data = null;
try {
data = JSON.parse(event.dataTransfer.getData("text/plain"));
console.log("Data", data.data);
let target = event.target.closest("[data-container-id]") as HTMLElement;
let containerId = target ? target.dataset.containerId : "";
console.log("Container ID", containerId);
data.data.system.containerId = containerId; //Update containerId
if (data.type !== "Transfer") return false;
} catch (err) {
return false;
@ -219,8 +558,20 @@ export default class M5CharacterSheet extends ActorSheet {
if (!data.data) return false;
if (data.actorId === this.actor.id) return false;
if (data.actorId === this.actor.id) {
let itemId=data.data._id;
const context = this.actor as any;
const item = context.items.get(itemId);
item.update({
data: {
containerId: data.data.system.containerId,
},
});
return this._onSortItem(event, data.data);
}
// limit transfer on personal weapons/armour/gear
if (["item", "weapon", "defensiveWeapon", "armor", "container"].includes(data.data.type)) {
try {
this.actor.createEmbeddedDocuments("Item", [duplicate(data.data)]); // Create a new Item
const actor = (game as any).actors.get(data.actorId);
@ -229,6 +580,10 @@ export default class M5CharacterSheet extends ActorSheet {
console.error("Error transfering item between actors", e);
return false;
}
} else {
ui.notifications.warn("Nur Gegenstände können übertragen werden.");
return false;
}
return true;
}

View File

@ -1,193 +1,179 @@
import { M5Item } from "../items/M5Item"
import { M5Attributes, M5ItemMod, M5ModOperation, M5ModType, M5RollTemplate } from "../M5Base"
import { M5Item } from "../items/M5Item";
import { M5Attributes, M5ItemMod, M5ModOperation, M5ModType, M5RollTemplate } from "../M5Base";
export class M5ItemSheet extends ItemSheet {
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
width: 640,
height: 480,
classes: ["midgard5", "sheet", "item"]
})
classes: ["midgard5", "sheet", "item"],
tabs: [
{
navSelector: ".sheet-navigation",
contentSelector: ".sheet-content",
initial: "base_values",
},
],
});
}
get template() {
//console.log("M5ItemSheet", this.item.data.type)
const path = "systems/midgard5/templates/sheets/item"
return `${path}/${this.item.type}.hbs`
const path = "systems/midgard5/templates/sheets/item";
return `${path}/${this.item.type}.hbs`;
}
override getData(options?: Partial<ItemSheet.Options>): ItemSheet.Data<ItemSheet.Options> | Promise<ItemSheet.Data<ItemSheet.Options>> {
const item = this.item as M5Item
return Promise.resolve(super.getData()).then(value => {
item.prepareDerivedData()
const context = value as any
const item = this.item as M5Item;
return Promise.resolve(super.getData()).then((value) => {
item.prepareDerivedData();
const context = value as any;
// Use a safe clone of the item data for further operations.
const itemData = context.item
const itemData = context.item;
// Retrieve the roll data for TinyMCE editors.
context.rollData = {}
let actor = this.object?.parent ?? null
context.rollData = {};
let actor = this.object?.parent ?? null;
if (actor) {
context.rollData = actor.getRollData()
context.rollData = actor.getRollData();
}
context.data = itemData.system
context.flags = itemData.flags
context.data = itemData.system;
context.flags = itemData.flags;
return context
})
return context;
});
}
override activateListeners(html: JQuery) {
super.activateListeners(html)
super.activateListeners(html);
html.find(".add-mod").on("click", async (event) => {
const context = this.object
const mods = context.system.mods
const modIndex = Object.keys(mods).length
const context = this.object;
const mods = context.system.mods;
const modIndex = Object.keys(mods).length;
mods[modIndex.toString()] = {
type: M5ModType.ATTRIBUTE,
id: M5Attributes.ST,
operation: M5ModOperation.ADD,
value: 0
} as M5ItemMod
value: 0,
} as M5ItemMod;
this.object.update({
data: {
mods: mods
}
})
})
mods: mods,
},
});
});
html.find(".item-delete").on("click", async (event) => {
let row = event.target.parentElement
let itemId = row.dataset["item"]
while (!itemId) {
row = row.parentElement
if (!row)
return
itemId = row.dataset["item"]
}
html.find(".mod-delete").on("click", async (event) => {
let target = event.target.closest("[data-mod-id]") as HTMLElement;
let modId = target ? target.dataset.modId : null;
const context = this.item
const item = context.items.get(itemId)
item.delete()
this.render(false)
})
const context = this.item;
delete context.system.mods[modId];
this.render(false);
});
html.find(".roll-delete").on("click", async (event) => {
//console.log("roll-delete", this.item.data.data.rolls.formulas)
let target = event.target.closest("[data-roll]") as HTMLElement;
let rollIndex = target ? target.dataset.roll : null;
let row = event.target.parentElement
let rollIndex = row.dataset["roll"]
while (!rollIndex) {
row = row.parentElement
if (!row)
return
rollIndex = row.dataset["roll"]
}
const rolls = this.item.system.rolls.formulas
rolls[rollIndex] = null
this.item.update({
data: {
rolls: {
formulas: rolls
}
}
})
this.render(false)
})
const rolls = this.item.system.rolls.formulas;
delete rolls[rollIndex];
this.render(false);
});
html.find(".roll-create").on("click", async (event) => {
const rolls = this.item.system.rolls.formulas
const rolls = this.item.system.rolls.formulas;
const indeces = Object.keys(rolls).map(index => parseInt(index)).sort().reverse()
const index = (indeces.find(index => !!rolls[index.toString()]) ?? -1) + 1
console.log("roll-create", rolls, indeces, index)
const indeces = Object.keys(rolls)
.map((index) => parseInt(index))
.sort()
.reverse();
const index = (indeces.find((index) => !!rolls[index.toString()]) ?? -1) + 1;
console.log("roll-create", rolls, indeces, index);
rolls[index.toString()] = {
formula: "1d6",
label: (game as Game).i18n.localize("midgard5.roll"),
enabled: true
} as M5RollTemplate
enabled: true,
} as M5RollTemplate;
this.item.update({
data: {
rolls: {
formulas: rolls
}
}
})
this.render(false)
})
formulas: rolls,
},
},
});
this.render(false);
});
// Drag & Drop
if (["item"].includes(this.object.type)) {
const itemToItemAssociation = new DragDrop({
dragSelector: ".item",
dropSelector: null,
permissions: { dragstart: this._canDragStart.bind(this), drop: this._canDragDrop.bind(this) },
dropSelector: ".item-list",
permissions: {
dragstart: this._canDragStart.bind(this),
drop: this._canDragDrop.bind(this),
},
callbacks: { drop: this._onDropItem.bind(this) },
})
itemToItemAssociation.bind(html[0])
});
itemToItemAssociation.bind(html[0]);
}
}
_canDragStart(selector) {
console.log("M5ItemSheet._canDragStart", selector)
return this.options.editable && this.object.isOwner
console.log("M5ItemSheet._canDragStart", selector);
return this.options.editable && this.object.isOwner;
}
_canDragDrop(selector) {
console.log("M5ItemSheet._canDragDrop", selector)
return true
console.log("M5ItemSheet._canDragDrop", selector);
return true;
}
async _onDropItem(event) {
let data
const obj = this.object
const li = event.currentTarget
let data;
const obj = this.object;
const li = event.currentTarget;
try {
data = JSON.parse(event.dataTransfer.getData("text/plain"))
if (data.type !== "Item")
return false
data = JSON.parse(event.dataTransfer.getData("text/plain"));
if (data.type !== "Item") return false;
} catch (err) {
return false
return false;
}
// Case 1 - Import from a Compendium pack
let itemObject
let itemObject;
if (data.pack) {
const compendiumObject = await (this as any).importItemFromCollection(data.pack, data.id)
itemObject = compendiumObject.data
const compendiumObject = await (this as any).importItemFromCollection(data.pack, data.id);
itemObject = compendiumObject.data;
}
// Case 2 - Import from World entity
else {
const originalItem = await (game as Game).items.get(data.id)
itemObject = duplicate(originalItem)
if (!itemObject)
return
const originalItem = await (game as Game).items.get(data.id);
itemObject = duplicate(originalItem);
if (!itemObject) return;
}
if ((itemObject.type === "mod")) {
let mods = obj?.system?.mods
if (!mods)
mods = []
if (itemObject.type === "mod") {
let mods = obj?.system?.mods;
if (!mods) mods = [];
itemObject.id = randomID()
console.log("M5ItemSheet._onDropItem", itemObject)
mods.push(itemObject)
itemObject.id = randomID();
console.log("M5ItemSheet._onDropItem", itemObject);
mods.push(itemObject);
obj.update({
data: {
mods: mods
}
})
mods: mods,
},
});
}
}

25
source/settings.ts Normal file
View File

@ -0,0 +1,25 @@
/* global game */
/**
* Define all game settings here
* @return {Promise}
*/
export const loadSettings = async function () {
(game as Game).settings.register("midgard5", "automatedPP", {
name: "Automatische Praxispunkte",
hint: "Falls aktiv, werden Praxispunkte automatisch angerechnet.",
scope: "world",
config: true,
default: true,
type: Boolean,
});
(game as Game).settings.register("midgard5", "automatedRoll", {
name: "Automatische Würfelwürfe",
hint: "Falls aktiv, wird bei Würfelwürfen kein Dialog gezeigt. Das Verhalten kann mit gleichzeitig gedrückter Shift Taste umgekehrt werden.",
scope: "world",
config: true,
default: false,
type: Boolean,
});
};

View File

@ -3,12 +3,89 @@
@attributeBorderColor: rgba(0, 0, 0, 0.5);
.midgard5 {
.flexbox {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.flexcolumn {
flex-wrap: wrap;
flex-direction: column;
}
.flexcolumn-1 {
flex-basis: 100%;
flex-wrap: wrap;
}
.flexcolumn-2 {
flex-basis: 50%;
flex-wrap: wrap;
}
.flexcolumn-3 {
flex-basis: 33%;
flex-wrap: wrap;
}
.flexcolumn-4 {
flex-basis: 25%;
flex-wrap: wrap;
}
.flexcolumn-5 {
flex-basis: 20%;
flex-wrap: wrap;
}
.flexpart {
gap: 0;
padding: 0;
margin: 2px;
background-color: beige;
border-collapse: separate;
border-radius: 10px;
border: 2px solid black;
}
.flexpart-header {
font-weight: bold;
font-size: large;
text-align: center;
color: black;
}
.flexpart-icon {
height: 2rem;
float: left;
border: 0px solid transparent;
}
.flexrow {
align-items: center;
}
h3 {
margin-top: 1rem;
padding: 0.5rem 0.5rem 0.5rem 0.5rem;
margin-top: 0.5rem;
margin-bottom: 0;
text-align: left;
font-weight: bold;
background-color: #eeede0;
color: black;
border-collapse: separate;
border: 2px solid black;
border-radius: 10px;
}
.profile-img {
display: block;
margin-left: auto;
margin-right: auto;
height: 100%;
width: auto;
border: 0px solid black;
}
.sheet.character {
@ -27,24 +104,51 @@
}
}
.profile-img {
height: 64px;
width: 64px;
}
.description {
flex: 0 0 100%;
margin: 0;
}
}
.sheet-navigation {
margin: 4px 0;
background-color: lightgrey;
border-top: 2px solid black;
border-bottom: 2px solid black;
}
.sheet-navigation .item {
padding: 8px 12px 8px 12px;
color: black;
font-weight: bold;
font-size: large;
}
.sheet-navigation .active {
background-color: darkgrey;
}
.level-display {
text-align: right;
font-weight: bold;
}
td, th {
table {
background-color: beige;
border: 0px solid transparent;
&.bordered {
border-collapse: separate;
border: 2px solid black;
border-radius: 10px;
font-size: larger;
font-weight: bolder;
}
}
td,
th {
padding: 0 0.5rem 0 0.5rem;
text-align: left;
&.center {
text-align: center;
@ -54,6 +158,44 @@
width: 3rem;
text-align: center;
}
&.attribute {
text-align: center;
font-weight: bold;
}
&.attribute-value {
background: url(/icons/svg/d20-grey.svg) no-repeat;
background-size: 50px 50px;
background-position: center;
color: black;
text-align: center;
font-weight: bold;
height: 50px;
width: 50px;
}
&.title {
padding: 0.5rem 0.5rem 0.5rem 0.5rem;
text-align: left;
font-weight: bold;
}
&.highlight {
font-weight: bold;
font-style: italic;
}
}
.table-icon {
height: 1rem;
width: 1rem;
float: left;
border: 0px solid transparent;
}
input {
border: 0px solid black;
}
input.skill {
@ -64,21 +206,38 @@
width: 5rem;
}
input.checkbox {
width: 1rem;
height: 1rem;
}
.new-skill {
font-style: italic;
background: rgba(0, 0, 0, 0.3);
color: rgba(255, 255, 255);
button {
background: rgba(255, 255, 255, 0.5);
}
}
button.roll-button {
.roll-button {
background: url(/icons/svg/d20-black.svg) no-repeat;
background-size: 24px 24px;
width: 26px;
height: 26px;
background-size: 1rem 1rem;
border: #000000 solid 0px;
width: 1rem;
height: 1rem;
}
.wide-button {
margin: 0.25rem 0;
}
.learn-button {
padding: 0;
margin: 0;
height: 1rem;
width: 4rem;
background: rgba(255, 255, 255, 0.5);
font-size: smaller;
text-align: center;
line-height: 0.8rem;
}
span.spell-process {
@ -91,7 +250,7 @@
}
.health-bar {
height: 2rem;
height: 1rem;
background-color: rgba(0, 0, 0, 0.8);
display: flex;
flex-direction: row;
@ -99,8 +258,9 @@
padding: 1px;
//align-items: stretch;
input {
flex: 0 0 3rem;
input,
.max-value {
flex: 0 0 2rem;
text-align: center;
height: 100%;
background-color: rgba(109, 108, 102, 1);
@ -112,32 +272,46 @@
.lp-bar-item-empty,
.ap-bar-item-empty {
flex-grow: 1;
background-color: rgb(201, 201, 201);
background-color: white;
}
.lp-bar-item {
flex-grow: 1;
background-color: rgb(57, 234, 139);
background-color: lightgreen;
}
.ap-bar-item {
flex-grow: 1;
background-color: rgb(57, 163, 234);
background-color: lightblue;
}
.negative-bar-item {
flex-grow: 1;
background-color: rgb(234, 57, 57);
background-color: red;
}
}
.biography {
margin: 0.5rem 0.5rem 0.5rem 0.5rem;
height: 180px;
background-color: #eaead7;
.editor {
height: 100%;
width: 100%;
}
}
.attributes {
padding: 0.5rem 0.5rem 0.5rem 0.5rem;
display: flex;
flex-direction: row;
margin-bottom: 0.5rem;
background-color: beige;
flex-wrap: wrap;
justify-content: center;
.attribute {
flex: 0 0 7rem;
flex: 0 0 6rem;
margin: 0;
border: 1px solid @attributeBorderColor;
//border-bottom: none;
@ -191,4 +365,36 @@
}
}
}
.chip {
display: inline-block;
padding: 0 25px;
height: 35px;
font-size: 16px;
line-height: 35px;
border-radius: 25px;
background-color: #f1f1f1;
}
.closebtn {
padding-left: 10px;
color: #888;
font-weight: bold;
float: right;
font-size: 20px;
cursor: pointer;
}
.closebtn:hover {
color: #000;
}
.pp-listing {
margin: 0 2rem;
flex: 1 0 16%;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: baseline;
}
}

View File

@ -18,7 +18,8 @@
width: 64px;
}
td, th {
td,
th {
padding: 0 0.5rem 0 0.5rem;
&.center {

View File

@ -0,0 +1,23 @@
// main: midgard5.less
@borderGroove: 2px groove #eeede0;
@attributeBorderColor: rgba(0, 0, 0, 0.5);
.midgard5 {
.sheet-npc {
.attribute-header {
align-items: center;
text-align: center;
font-weight: bold;
border: 0px solid transparent;
}
.attribute-value {
align-items: center;
text-align: center;
border: 0px solid transparent;
}
.fixed-value {
width: 3rem;
text-align: center;
}
}
}

View File

@ -7,6 +7,14 @@
font-size: 1.3rem;
}
.roll-description-header {
text-align: start;
vertical-align: middle;
padding: 0.3rem 0 0.1rem 0;
font-weight: bold;
font-size: 1.2rem;
}
.roll-spell-details {
text-align: right;
padding-right: 1rem;

View File

@ -1,59 +1,21 @@
{
"id": "midgard5",
"name": "midgard5",
"title": "Midgard 5. Edition",
"description": "The German RPG Midgard 5. Edition",
"version": "1.2.0",
"version": "2.7.2",
"compatibility": {
"minimum": "10",
"verified": "10"
"verified": "11",
"maximum": "11"
},
"authors": [{ "name": "Byroks" }],
"authors": [
{"name": "Byroks"},
{"name": "Le-Frique"},
{"name": "Oskaloq"}
],
"scripts": ["bundle.js"],
"styles": ["bundle.css"],
"packs": [
{
"name": "blaupause-spielfiguren",
"label": "Blaupausen für Spielfiguren",
"system": "midgard5",
"path": "./packs/actors/blaupause-spielfiguren.db",
"type": "Actor"
},
{
"name": "blaupause-gegenstaende",
"label": "Blaupausen für Gegenstände",
"system": "midgard5",
"path": "./packs/items/blaupause-gegenstaende.db",
"type": "Item"
},
{
"name": "tabellen-kritische-ereignisse",
"label": "Tabellen Kritische Ereignisse",
"system": "midgard5",
"path": "./packs/rolltables/tabellen-kritische-ereignisse.db",
"type": "RollTable"
},
{
"name": "makros-kritische-ereignisse",
"label": "Makros Kritische Ereignisse",
"system": "midgard5",
"path": "./packs/macros/makros-kritische-ereignisse.db",
"type": "Macro"
},
{
"name": "makros-standardwurfel",
"label": "Standardwürfel",
"system": "midgard5",
"path": "./packs/macros/makros-standardwurfel.db",
"type": "Macro"
},
{
"name": "scenes-midgard-karten",
"label": "Midgard-Karten",
"system": "midgard5",
"path": "./packs/scenes/scenes-midgard-karten.db",
"type": "Scene"
}
],
"languages": [
{
"lang": "de",
@ -65,9 +27,9 @@
"gridUnits": "m",
"primaryTokenAttribute": "lp",
"secondaryTokenAttribute": "ap",
"url": "https://github.com/Byroks/foundry-vtt-system-midgard5",
"manifest": "https://github.com/Byroks/foundry-vtt-system-midgard5/releases/download/v1.2.0/system.json",
"download": "https://github.com/Byroks/foundry-vtt-system-midgard5/releases/download/v1.2.0/midgard5-v1.2.0.zip",
"initiative": "@calc.attributes.gw.value",
"url": "https://git.byroks.de/MidgardVTT-Entwicklung/foundry-vtt-system-midgard5",
"manifest": "https://git.byroks.de/MidgardVTT-Entwicklung/foundry-vtt-system-midgard5/releases/download/latest/system.json?token=2455375115b92bc8d87c93df7159eec232456f2d",
"download": "https://git.byroks.de/MidgardVTT-Entwicklung/foundry-vtt-system-midgard5/releases/download/latest/midgard5.zip?token=2455375115b92bc8d87c93df7159eec232456f2d",
"initiative": "@c.calc.attributes.gw.value",
"license": "LICENSE.txt"
}

View File

@ -1,11 +1,16 @@
{
"Actor": {
"types": ["character"],
"types": [
"character",
"npc"
],
"templates": {
"characterDescription": {
"info": {
"description": "",
"class": "",
"background": "",
"class": {},
"npc-class": "",
"race": "",
"magicUsing": false,
"gender": "",
@ -16,7 +21,13 @@
"caste": "",
"occupation": "",
"origin": "",
"faith": ""
"faith": "",
"level": 1,
"gold": 0,
"silver": 0,
"copper": 0,
"showAllItems": false,
"showUnlearned": false
}
},
"characterBars": {
@ -36,9 +47,11 @@
"ep": 0,
"gg": 0,
"sg": 0,
"gp": 2
"gp": 0
},
"attributes": {
"level": 1,
"movement": 24,
"attributes": {
"st": { "value": 50, "bonus": 0 },
"gs": { "value": 50, "bonus": 0 },
@ -48,74 +61,122 @@
"zt": { "value": 50, "bonus": 0 },
"au": { "value": 50, "bonus": 0 },
"pa": { "value": 50, "bonus": 0 },
"wk": { "value": 50, "bonus": 0 }
"wk": { "value": 50, "bonus": 0 },
"git": { "value": 50, "bonus": 0 }
}
},
"skills": {
"skills": {
"general": {
"abrichten": { "fw": 0, "attribute": "pa", "initial": 8, "pp": 0 },
"akrobatik": { "fw": 6, "attribute": "gw", "initial": 8, "pp": 0 },
"alchimie": { "fw": 0, "attribute": "in", "initial": 8, "pp": 0 },
"anfuehren": { "fw": 6, "attribute": "pa", "initial": 8, "pp": 0 },
"askese": { "fw": 0, "attribute": "wk", "initial": 8, "pp": 0 },
"astrologie": { "fw": 0, "attribute": "in", "initial": 8, "pp": 0 },
"athletik": { "fw": 0, "attribute": "st", "initial": 8, "pp": 0 },
"balancieren": { "fw": 6, "attribute": "gw", "initial": 8, "pp": 0 },
"beidhaendigerKampf": { "fw": 0, "attribute": "gs", "initial": 8, "pp": 0 },
"beredsamkeit": { "fw": 3, "attribute": "pa", "initial": 8, "pp": 0 },
"bergreiten": { "fw": 0, "attribute": "gw", "initial": 12, "pp": 0 },
"betaeuben": { "fw": 6, "attribute": "gs", "initial": 8, "pp": 0 },
"betaeubungsgriff": { "fw": 0, "attribute": "in", "initial": 8, "pp": 0 },
"bildendeKuensteA": { "fw": 0, "attribute": "gs", "initial": 12, "pp": 0 },
"bildendeKuensteB": { "fw": 0, "attribute": "gs", "initial": 12, "pp": 0 },
"bildendeKuensteG": { "fw": 0, "attribute": "gs", "initial": 12, "pp": 0 },
"bildendeKuensteM": { "fw": 0, "attribute": "gs", "initial": 12, "pp": 0 },
"bootfahren": { "fw": 3, "attribute": "gs", "initial": 8, "pp": 0 },
"dickhaeuterLenken": { "fw": 0, "attribute": "gs", "initial": 8, "pp": 0 },
"ersteHilfe": { "fw": 0, "attribute": "gs", "initial": 8, "pp": 0 },
"etikette": { "fw": 0, "attribute": "in", "initial": 8, "pp": 0 },
"fallenEntdecken": { "fw": 0, "attribute": "in", "initial": 8, "pp": 0 },
"fallenmechanik": { "fw": 0, "attribute": "gs", "initial": 8, "pp": 0 },
"faelschen": { "fw": 0, "attribute": "gs", "initial": 8, "pp": 0 },
"faelschen": { "fw": 0, "attribute": "gs", "initial": 12, "pp": 0 },
"fangen": { "fw": 6, "attribute": "gs", "initial": 8, "pp": 0 },
"fechten": { "fw": 0, "attribute": "gs", "initial": 8, "pp": 0 },
"feueralchimie": { "fw": 0, "attribute": "gs", "initial": 8, "pp": 0 },
"gassenwissen": { "fw": 0, "attribute": "in", "initial": 8, "pp": 0 },
"gaukeln": { "fw": 0, "attribute": "gs", "initial": 8, "pp": 0 },
"gaukeln": { "fw": 0, "attribute": "gs", "initial": 12, "pp": 0 },
"gelaendelauf": { "fw": 6, "attribute": "gw", "initial": 8, "pp": 0 },
"geraetekunde": { "fw": 0, "attribute": "in", "initial": 8, "pp": 0 },
"geschaeftssinn": { "fw": 0, "attribute": "in", "initial": 8, "pp": 0 },
"gluecksspiel": { "fw": 0, "attribute": "gs", "initial": 8, "pp": 0 },
"gluecksspiel": { "fw": 0, "attribute": "gs", "initial": 12, "pp": 0 },
"heilkunde": { "fw": 0, "attribute": "in", "initial": 8, "pp": 0 },
"kampfInVollruestung": { "fw": 0, "attribute": "st", "initial": 8, "pp": 0 },
"kampfInVollruestung": { "fw": 0, "attribute": "st", "initial": 5, "pp": 0 },
"kampfInSchlachtreihe": { "fw": 0, "attribute": "gs", "initial": 8, "pp": 0 },
"kampfkunst": { "fw": 0, "attribute": "gw", "initial": 8, "pp": 0 },
"kido": { "fw": 0, "attribute": "zt", "initial": 8, "pp": 0 },
"klettern": { "fw": 6, "attribute": "st", "initial": 8, "pp": 0 },
"landeskunde": { "fw": 6, "attribute": "in", "initial": 8, "pp": 0 },
"laufen": { "fw": 0, "attribute": "ko", "initial": 8, "pp": 0 },
"lesenVonZauberschrift": { "fw": 0, "attribute": "in", "initial": 8, "pp": 0 },
"lesenVonZauberrunen": { "fw": 0, "attribute": "in", "initial": 8, "pp": 0 },
"meditieren": { "fw": 0, "attribute": "wk", "initial": 8, "pp": 0 },
"menschenkenntnis": { "fw": 3, "attribute": "in", "initial": 8, "pp": 0 },
"meucheln": { "fw": 0, "attribute": "gs", "initial": 8, "pp": 0 },
"musizieren": { "fw": 0, "attribute": "gs", "initial": 8, "pp": 0 },
"musizierenFloete": { "fw": 0, "attribute": "gs", "initial": 12, "pp": 0 },
"musizierenBlas": { "fw": 0, "attribute": "gs", "initial": 12, "pp": 0 },
"musizierenRythmus": { "fw": 0, "attribute": "gs", "initial": 12, "pp": 0 },
"musizierenStreich": { "fw": 0, "attribute": "gs", "initial": 12, "pp": 0 },
"musizierenZupf": { "fw": 0, "attribute": "gs", "initial": 12, "pp": 0 },
"ninjutsu": { "fw": 0, "attribute": "gw", "initial": 8, "pp": 0 },
"naturkunde": { "fw": 0, "attribute": "in", "initial": 8, "pp": 0 },
"orakelkunst": { "fw": 0, "attribute": "in", "initial": 8, "pp": 0 },
"pflanzenkunde": { "fw": 0, "attribute": "in", "initial": 8, "pp": 0 },
"reiten": { "fw": 6, "attribute": "gw", "initial": 8, "pp": 0 },
"raunen": { "fw": 0, "attribute": "zt", "initial": 8, "pp": 0 },
"reiten": { "fw": 6, "attribute": "gw", "initial": 12, "pp": 0 },
"reiterkampf": { "fw": 0, "attribute": "gw", "initial": 8, "pp": 0 },
"rutengehen": { "fw": 0, "attribute": "in", "initial": 8, "pp": 0 },
"scharfschiessen": { "fw": 0, "attribute": "gs", "initial": 8, "pp": 0 },
"schiesskunst": { "fw": 0, "attribute": "gs", "initial": 8, "pp": 0 },
"schmerzErtragen": { "fw": 0, "attribute": "wk", "initial": 8, "pp": 0 },
"selbstkontrolle": { "fw": 0, "attribute": "wk", "initial": 12, "pp": 0 },
"speerfechten": { "fw": 0, "attribute": "gs", "initial": 5, "pp": 0 },
"schleichen": { "fw": 3, "attribute": "gw", "initial": 8, "pp": 0 },
"schloesserOeffnen": { "fw": 0, "attribute": "gs", "initial": 8, "pp": 0 },
"schwimmen": { "fw": 3, "attribute": "gw", "initial": 8, "pp": 0 },
"singen": { "fw": 0, "attribute": "pa", "initial": 8, "pp": 0 },
"seilkunst": { "fw": 3, "attribute": "gs", "initial": 8, "pp": 0 },
"skifahren": { "fw": 6, "attribute": "gw", "initial": 12, "pp": 0 },
"spinnengang": { "fw": 0, "attribute": "gw", "initial": 8, "pp": 0 },
"spurensuche": { "fw": 0, "attribute": "in", "initial": 8, "pp": 0 },
"stehlen": { "fw": 3, "attribute": "gs", "initial": 8, "pp": 0 },
"tarnen": { "fw": 3, "attribute": "gw", "initial": 8, "pp": 0 },
"thaumagraphie": { "fw": 0, "attribute": "zt", "initial": 8, "pp": 0 },
"thaumalogie": { "fw": 0, "attribute": "in", "initial": 8, "pp": 0 },
"taitschi": { "fw": 0, "attribute": "wk", "initial": 8, "pp": 0 },
"tauchen": { "fw": 6, "attribute": "ko", "initial": 8, "pp": 0 },
"tanzen": { "fw": 6, "attribute": "ko", "initial": 8, "pp": 0 },
"tierkunde": { "fw": 0, "attribute": "in", "initial": 8, "pp": 0 },
"ueberleben": { "fw": 6, "attribute": "in", "initial": 8, "pp": 0 },
"ueberlebenWald": { "fw": 6, "attribute": "in", "initial": 8, "pp": 0 },
"ueberlebenSteppe": { "fw": 6, "attribute": "in", "initial": 8, "pp": 0 },
"ueberlebenGebirge": { "fw": 6, "attribute": "in", "initial": 8, "pp": 0 },
"verfuehren": { "fw": 3, "attribute": "pa", "initial": 8, "pp": 0 },
"verhoeren": { "fw": 3, "attribute": "pa", "initial": 8, "pp": 0 },
"verstellen": { "fw": 3, "attribute": "pa", "initial": 8, "pp": 0 },
"volkstanz": { "fw": 3, "attribute": "gw", "initial": 8, "pp": 0 },
"wagenlenken": { "fw": 3, "attribute": "gs", "initial": 8, "pp": 0 },
"wahrsagen": { "fw": 0, "attribute": "zt", "initial": 8, "pp": 0 },
"wasserkampf": { "fw": 0, "attribute": "gw", "initial": 8, "pp": 0 },
"zauberkunde": { "fw": 0, "attribute": "in", "initial": 8, "pp": 0 }
}
}
},
"gear": {
"gear": {}
}
},
"character": {
"templates": ["characterBars", "attributes", "characterDescription", "characterHeader", "skills"],
"templates": ["characterBars", "attributes", "characterDescription", "characterHeader", "skills", "gear"],
"calc": {}
},
"npc": {
"templates": ["characterBars", "attributes", "characterDescription", "skills", "gear"],
"calc": {}
}
},
"Item": {
"types": ["skill", "weapon", "defensiveWeapon", "armor", "spell", "item"],
"types": ["skill", "weapon", "defensiveWeapon", "armor", "spell", "kampfkunst", "item", "effect", "container", "class"],
"templates": {
"itemDescription": {
"description": ""
@ -165,32 +226,65 @@
},
"equippable": {
"equippable": false,
"equipped": true
"equipped": false
},
"valuable": {
"valuable": false,
"item-wealth": true
},
"hoarded": {
"hoarded": false,
"inHoard": true
},
"physical": {
"value": 0,
"magic": false
"weight": 0,
"capacity": 0,
"containerId": "",
"magic": false,
"abw": 0
},
"durationSelection": {
"durationSelection": {
"round": "midgard5.time-round",
"minute": "midgard5.time-minute",
"hour": "midgard5.time-hour",
"limitless": "midgard5.time-limitless"
}
},
"spellSelection": {
"spellProcessSelection": {
"none": "midgard5.spell-process-none",
"artefakte": "midgard5.spell-process-artefakte",
"beherrschen": "midgard5.spell-process-beherrschen",
"bewegen": "midgard5.spell-process-bewegen",
"beschwoeren": "midgard5.spell-process-beschwoeren",
"blutmagie": "midgard5.spell-process-blutmagie",
"chaoswunder": "midgard5.spell-process-chaoswunder",
"dweomer": "midgard5.spell-process-dweomer",
"erhaltung": "midgard5.spell-process-erhaltung",
"erkennen": "midgard5.spell-process-erkennen",
"erschaffen": "midgard5.spell-process-erschaffen",
"formen": "midgard5.spell-process-formen",
"veraendern": "midgard5.spell-process-veraendern",
"zerstoeren": "midgard5.spell-process-zerstoeren",
"wundertat": "midgard5.spell-process-wundertat",
"dweomer": "midgard5.spell-process-dweomer",
"zauberlied": "midgard5.spell-process-zauberlied",
"salz": "midgard5.spell-process-salz",
"thaumagraphie": "midgard5.spell-process-thaumagraphie",
"beschwoeren": "midgard5.spell-process-beschwoeren",
"finstere_magie": "midgard5.spell-process-finstere_magie",
"kampfverse": "midgard5.spell-process-kampfverse",
"namensmagie": "midgard5.spell-process-namensmagie",
"nekromantie": "midgard5.spell-process-nekromantie",
"thaumatherapie": "midgard5.spell-process-thaumatherapie",
"runenstaebe": "midgard5.spell-process-zauberrunen",
"thaumatherapie": "midgard5.spell-process-runenstaebe",
"veraendern": "midgard5.spell-process-veraendern",
"vigilsignien": "midgard5.spell-process-vigilsignien",
"wilder_dweomer": "midgard5.spell-process-wilder_dweomer",
"wundertat": "midgard5.spell-process-wundertat",
"zauberblaetter": "midgard5.spell-process-zauberblaetter",
"zauberlied": "midgard5.spell-process-zauberlied",
"zaubermittel": "midgard5.spell-process-zaubermittel",
"zauberschutz": "midgard5.spell-process-zauberschutz"
"zauberrunen": "midgard5.spell-process-zauberrunen",
"zaubersalz": "midgard5.spell-process-zaubersalz",
"zauberschutz": "midgard5.spell-process-zauberschutz",
"zaubersiegel": "midgard5.spell-process-zaubersiegel",
"zaubertaenze": "midgard5.spell-process-zaubertaenze",
"zerstoeren": "midgard5.spell-process-zerstoeren"
},
"spellTypeSelection": {
"gedanke": "midgard5.spell-type-gedanke",
@ -201,6 +295,45 @@
"umgebung": "midgard5.spell-target-umgebung",
"geist": "midgard5.spell-target-geist",
"koerper": "midgard5.spell-target-koerper"
},
"spellSpecialization": "none"
},
"kampfkunstSelection": {
"kampfkunstTypeSelection": {
"angriff": "midgard5.kampfkunst-type-angriff",
"verteidigung": "midgard5.kampfkunst-type-verteidigung",
"finte": "midgard5.kampfkunst-type-finte",
"geist": "midgard5.kampfkunst-type-geist",
"schießkunst": "midgard5.kampfkunst-type-schießkunst",
"fechtkunst": "midgard5.kampfkunst-type-fechtkunst"
},
"kidoTypeSelection": {
"angriff": "midgard5.kido-type-angriff",
"verteidigung": "midgard5.kido-type-verteidigung",
"finte": "midgard5.kido-type-finte",
"leib": "midgard5.kido-type-leib"
},
"kampfkunstVarianteSelection": {
"anstuermen": "midgard5.kampfkunst-variante-anstuermen",
"attackieren": "midgard5.kampfkunst-variante-attackieren",
"entwaffnen": "midgard5.kampfkunst-variante-entwaffnen",
"fechten": "midgard5.kampfkunst-variante-fechten",
"schusstechnik": "midgard5.kampfkunst-variante-schusstechnik",
"finten": "midgard5.kampfkunst-variante-finten",
"geistestechnik": "midgard5.kampfkunst-variante-geistestechnik",
"verteidigung": "midgard5.kampfkunst-variante-verteidigung"
},
"kidoVarianteSelection": {
"none": "midgard5.spell-process-none",
"anspringen": "midgard5.kido-variante-anspringen",
"attackieren": "midgard5.kido-variante-attackieren",
"entwaffnen": "midgard5.kido-variante-entwaffnen",
"werfen": "midgard5.kido-variante-werfen",
"ausweichen": "midgard5.kido-variante-ausweichen",
"blockieren": "midgard5.kido-variante-blockieren",
"bewegen": "midgard5.kido-variante-bewegen",
"kontrollieren": "midgard5.kido-variante-kontrollieren",
"finte": "midgard5.kido-variante-finte"
}
}
},
@ -208,6 +341,7 @@
"templates": ["itemDescription", "attributeSelection"],
"fw": 0,
"attribute": "st",
"equipped": true,
"skill": "",
"type": "general",
"rolls": {
@ -221,9 +355,19 @@
"output": ""
},
"pp": 0,
"calc": {}
"calc": {},
"mods": {}
},
"item": {
"templates": ["itemDescription", "equippable", "physical", "valuable", "hoarded"],
"rolls": {
"formulas": {},
"output": ""
},
"mods": {},
"calc": {}
},
"container": {
"templates": ["itemDescription", "equippable", "physical"],
"rolls": {
"formulas": {},
@ -232,12 +376,24 @@
"mods": {},
"calc": {}
},
"effect": {
"templates": ["itemDescription", "equippable", "physical", "durationSelection"],
"rolls": {
"formulas": {},
"output": ""
},
"mods": {},
"calc": {}
},
"weapon": {
"templates": ["itemDescription", "stats", "equippable", "physical"],
"templates": ["itemDescription", "stats", "equippable", "physical", "valuable", "hoarded"],
"special": false,
"ranged": false,
"valuable": false,
"hoarded": false,
"skillId": "",
"damageBase": "1d6",
"ew": 5,
"rolls": {
"formulas": {
"0": {
@ -256,8 +412,10 @@
"calc": {}
},
"defensiveWeapon": {
"templates": ["itemDescription", "stats", "equippable", "physical"],
"templates": ["itemDescription", "stats", "equippable", "physical", "valuable", "hoarded"],
"special": false,
"valuable": false,
"hoarded": false,
"skillId": "",
"rolls": {
"formulas": {
@ -272,14 +430,17 @@
"calc": {}
},
"armor": {
"templates": ["itemDescription", "stats", "equippable", "attributeMod", "physical"],
"templates": ["itemDescription", "stats", "equippable", "attributeMod", "physical", "valuable", "hoarded"],
"lpProtection": 0,
"apProtection": 0,
"valuable": false,
"hoarded": false,
"rolls": {
"formulas": {},
"output": ""
},
"calc": {}
"calc": {},
"mods": {}
},
"spell": {
"templates": ["itemDescription", "spellSelection"],
@ -287,12 +448,17 @@
"type": "",
"process": "",
"ap": "",
"lp": "",
"castDuration": "",
"range": "",
"effectTarget": "",
"effectArea": "",
"effectDuration": "",
"origin": "",
"agens": "",
"reagens": "",
"material": "",
"rank": 0,
"rolls": {
"formulas": {
"0": {
@ -304,6 +470,180 @@
"output": ""
},
"calc": {}
},
"kampfkunst": {
"templates": ["itemDescription", "kampfkunstSelection"],
"bonus": 0,
"type": "",
"variante": "",
"isKido": false,
"ap": "",
"weapon": "",
"ep": "",
"rank": 0,
"enemy": "",
"color": "",
"style": "",
"grade": "",
"rolls": {
"formulas": {
"0": {
"formula": "1d20 + @i.calc.ew + @i.bonus",
"label": "Kampfkunst",
"enabled": true
}
},
"output": ""
},
"calc": {}
},
"class": {
"templates": ["itemDescription"],
"magicUsing": false,
"equipped": true,
"resistanceBody": 1,
"resistanceMind": 0,
"calc": {},
"mods": {},
"lernKostenAllgemein": {
"alltag": 20,
"freiland": 20,
"halbwelt": 20,
"kampf": 20,
"koerper": 20,
"sozial": 20,
"unterwelt": 20,
"waffen": 20,
"wissen": 20
},
"lernKostenZauber": {
"beherrschen": {
"kosten": 0,
"pp": 0
},
"bewegen": {
"kosten": 0,
"pp": 0
},
"erkennen": {
"kosten": 0,
"pp": 0
},
"erschaffen": {
"kosten": 0,
"pp": 0
},
"formen": {
"kosten": 0,
"pp": 0
},
"veraendern": {
"kosten": 0,
"pp": 0
},
"zerstoeren": {
"kosten": 0,
"pp": 0
},
"wundertat": {
"kosten": 0,
"pp": 0
},
"dweomer": {
"kosten": 0,
"pp": 0
},
"zauberlied": {
"kosten": 0,
"pp": 0
},
"kampfverse": {
"kosten": 0,
"pp": 0
},
"zaubertaenze": {
"kosten": 0,
"pp": 0
},
"zaubersalz": {
"kosten": 0,
"pp": 0
},
"runenstaebe": {
"kosten": 0,
"pp": 0
},
"zaubersiegel": {
"kosten": 0,
"pp": 0
},
"zauberrunen": {
"kosten": 0,
"pp": 0
},
"thaumagraphie": {
"kosten": 0,
"pp": 0
},
"erhaltung": {
"kosten": 0,
"pp": 0
},
"zaubermittel": {
"kosten": 0,
"pp": 0
},
"zauberschutz": {
"kosten": 0,
"pp": 0
},
"zauberblaetter": {
"kosten": 0,
"pp": 0
},
"vigilsignien": {
"kosten": 0,
"pp": 0
},
"artefakte": {
"kosten": 0,
"pp": 0
},
"chaoswunder": {
"kosten": 0,
"pp": 0
},
"wilder_dweomer": {
"kosten": 0,
"pp": 0
},
"nekromantie": {
"kosten": 0,
"pp": 0
},
"finstere_magie": {
"kosten": 0,
"pp": 0
},
"blutmagie": {
"kosten": 0,
"pp": 0
},
"beschwoeren": {
"kosten": 0,
"pp": 0
},
"namensmagie": {
"kosten": 0,
"pp": 0
}
},
"lernKostenKamptechnik": {
"kampfkunst": 90,
"fechtkunst": 90,
"schiesskunst": 90,
"kido": 90
}
}
}
}

View File

@ -0,0 +1,18 @@
<form>
<div class="window-content">
<label><b>Wahl der Kosten</b></label>
<hr />
<span class="dice-tooltip">
<div class="dice-rolls flexrow">
<div>
{{localize "midgard5.destiny"}}:
{{sg}}
</div>
<div>
{{localize "midgard5.luckPoints"}}:
{{gp}}
</div>
</div>
</span>
</div>
</form>

View File

@ -9,6 +9,10 @@
<td>{{localize "midgard5.actor-ap"}}</td>
<td class="roll-spell-details">{{i.ap}}</td>
</tr>
<tr>
<td>{{localize "midgard5.actor-lp"}}</td>
<td class="roll-spell-details">{{i.lp}}</td>
</tr>
<tr>
<td>{{localize "midgard5.spell-castDuration"}}</td>
<td class="roll-spell-details">{{i.castDuration}}</td>
@ -41,14 +45,87 @@
<td>{{localize "midgard5.spell-process"}}</td>
<td class="roll-spell-details">{{localize (m5concat "midgard5.spell-process-" i.process)}}</td>
</tr>
<tr>
<td>{{localize "midgard5.spell-agens"}}</td>
<td class="roll-spell-details">{{i.agens}}</td>
<tr/>
<td>{{localize "midgard5.spell-reagens"}}</td>
<td class="roll-spell-details">{{i.reagens}}</td>
</tr>
<tr>
<td>{{localize "midgard5.spell-material"}}</td>
<td class="roll-spell-details">{{i.material}}</td>
<tr/>
{{/if}}
{{#if (eq iType "kampfkunst")}}
{{#unless i.isKido}}
<tr>
<td>{{localize "midgard5.actor-ap"}}</td>
<td class="roll-spell-details">{{i.ap}}</td>
</tr>
<tr>
<td>{{localize "midgard5.kampfkunst-ep"}}</td>
<td class="roll-spell-details">{{i.ep}}</td>
</tr>
<tr>
<td>{{localize "midgard5.kampfkunst-type"}}</td>
<td class="roll-spell-details">{{localize (m5concat "midgard5.kampfkunst-type-" i.type)}}</td>
</tr>
<tr>
<td>{{localize "midgard5.kampfkunst-variante"}}</td>
<td class="roll-spell-details">{{localize (m5concat "midgard5.kampfkunst-variante-" i.variante)}}</td>
</tr>
<tr>
<td>{{localize "midgard5.kampfkunst-enemy"}}</td>
<td class="roll-spell-details">{{i.enemy}}</td>
</tr>
<tr>
<td>{{localize "midgard5.kampfkunst-weapon"}}</td>
<td class="roll-spell-details">{{i.weapon}}</td>
</tr>
{{else}}
<tr>
<td>{{localize "midgard5.actor-ap"}}</td>
<td class="roll-spell-details">{{i.ap}}</td>
</tr>
<tr>
<td>{{localize "midgard5.kampfkunst-ep"}}</td>
<td class="roll-spell-details">{{i.ep}}</td>
</tr>
<tr>
<td>{{localize "midgard5.kido-color"}}</td>
<td class="roll-spell-details">{{i.color}}</td>
</tr>
<tr>
<td>{{localize "midgard5.kido-style"}}</td>
<td class="roll-spell-details">{{i.style}}</td>
</tr>
<tr>
<td>{{localize "midgard5.kido-type"}}</td>
<td class="roll-spell-details">{{localize (m5concat "midgard5.kido-type-" i.type)}}</td>
</tr>
<tr>
<td>{{localize "midgard5.kido-variante"}}</td>
<td class="roll-spell-details">{{localize (m5concat "midgard5.kido-variante-" i.variante)}}</td>
</tr>
<tr>
<td>{{localize "midgard5.kido-enemy"}}</td>
<td class="roll-spell-details">{{i.enemy}}</td>
</tr>
<tr>
<td>{{localize "midgard5.kido-weapon"}}</td>
<td class="roll-spell-details">{{i.weapon}}</td>
</tr>
{{/unless}}
{{/if}}
{{#each rolls as |roll index|}}
{{#if roll.enabled}}
<tr class="roll-row {{roll.css}}">
<td>{{roll.label}}</td>
<td>{{roll.label}} {{#if (eq index '0')}} {{#if (gt ../b.modifier 0)}}+{{../b.modifier}}{{/if}}{{#if (gt 0 ../b.modifier)}}{{../b.modifier}}{{/if}}{{/if}}</td>
<td class="roll-result">
<span class="roll-total">{{roll.totalStr}}</span>
<span class="roll-total {{#if (contains roll.label "Schaden")}}apply damage{{/if}}{{#if (contains roll.label "Heilung")}}apply heal{{/if}}">{{roll.totalStr}}</span>
<span class="roll-detail">{{roll.result}}</span>
</td>
</tr>
@ -56,5 +133,11 @@
{{/each}}
</tbody>
</table>
{{#if i.description}}
<tr>
<h2 class="roll-description-header">Beschreibung:</h2>
<span>{{stripHtml i.description}}</span>
</tr>
{{/if}}
</div>
</div>

View File

@ -0,0 +1,22 @@
<form>
<div class="form-group">
<label>{{localize "midgard5.chat.options.modifier"}}</label>
<input type="number" name="modifier" value="{{modifier}}" />
</div>
{{#unless isPW}}
<div class="form-group">
<label>{{localize "midgard5.chat.options.difficulty"}}</label>
<input type="number" name="difficulty" value="{{difficulty}}" />
</div>
{{/unless}}
<div class="form-group">
<label>{{localize "midgard5.chat.options.rollMode"}}</label>
<select name="rollMode">
{{#select rollMode}}
{{#each rollModes as |label mode|}}
<option value="{{mode}}">{{localize label}}</option>
{{/each}}
{{/select}}
</select>
</div>
</form>

View File

@ -1,66 +1,8 @@
<div class="flexbox">
<h3>{{localize "midgard5.actor-lp"}}</h3>
<div>
<div class="health-bar">
<input name="data.lp.value" type="text" value="{{data.lp.value}}" data-dtype="Number" />
{{#times data.lp.max}}
{{#if (lt this ../data.lp.value)}}
<div class="lp-bar-item update-lp" data-value="{{this}}"></div>
{{else}}
<div class="lp-bar-item-empty update-lp" data-value="{{this}}"></div>
{{/if}}
{{/times}}
<input name="data.lp.max" type="text" value="{{data.lp.max}}" data-dtype="Number" />
</div>
</div>
<h3>{{localize "midgard5.actor-ap"}}</h3>
<div>
<div class="health-bar">
<input name="data.ap.value" type="text" value="{{data.ap.value}}" data-dtype="Number" />
{{#times data.ap.max}}
{{#if (lt this ../data.ap.value)}}
<div class="ap-bar-item update-ap" data-value="{{this}}"></div>
{{else}}
<div class="ap-bar-item-empty update-ap" data-value="{{this}}"></div>
{{/if}}
{{/times}}
<input name="data.ap.max" type="text" value="{{data.ap.max}}" data-dtype="Number" />
</div>
</div>
<h3>Eigenschaften</h3>
<div class="flexrow">
<span class="flex0">{{localize "midgard5.class"}}</span>
<input class="flex3" name="data.info.class" type="text" value="{{data.info.class}}" data-dtype="String" />
<input id="data.info.magicUsing" type="checkbox" name="data.info.magicUsing" {{checked data.info.magicUsing}}>
<label class="flex0" for="data.info.magicUsing">{{localize "midgard5.magicUsing"}}</label>
<span class="level-display">Grad {{data.calc.level}}</span>
</div>
<table>
<tbody>
<tr>
<td>{{localize "midgard5.grace"}}</td>
<td><input name="data.gg" type="text" value="{{data.gg}}" data-dtype="Number" /></td>
<td>{{localize "midgard5.exp-overall"}}</td>
<td><input name="data.es" type="text" value="{{data.es}}" data-dtype="Number" /></td>
</tr>
<tr>
<td>{{localize "midgard5.destiny"}}</td>
<td><input name="data.sg" type="text" value="{{data.sg}}" data-dtype="Number" /></td>
<td>{{localize "midgard5.exp-available"}}</td>
<td><input name="data.ep" type="text" value="{{data.ep}}" data-dtype="Number" /></td>
</tr>
<tr>
<td>{{localize "midgard5.luckPoints"}}</td>
<td><input name="data.gp" type="text" value="{{data.gp}}" data-dtype="Number" /></td>
</tr>
</tbody>
</table>
<h3>Leiteigenschaften</h3>
<div class="flexpart">
<div class="flexpart-header"><img src="icons/skills/melee/maneuver-sword-katana-yellow.webp" class="flexpart-icon">{{localize "midgard5.attributes"}}</div>
<br>
<div class="attributes">
{{> "systems/midgard5/templates/sheets/character/attribute.hbs" attributeId="st" attribute=data.attributes.st calc=data.calc.attributes.st}}
<div class="filler"></div>
@ -71,23 +13,66 @@
{{> "systems/midgard5/templates/sheets/character/attribute.hbs" attributeId="ko" attribute=data.attributes.ko calc=data.calc.attributes.ko}}
<div class="filler"></div>
{{> "systems/midgard5/templates/sheets/character/attribute.hbs" attributeId="in" attribute=data.attributes.in calc=data.calc.attributes.in}}
</div>
<div class="attributes">
<div class="filler"></div>
{{> "systems/midgard5/templates/sheets/character/attribute.hbs" attributeId="zt" attribute=data.attributes.zt calc=data.calc.attributes.zt}}
<div class="attribute-filler-fixed"></div>
<div class="filler"></div>
{{> "systems/midgard5/templates/sheets/character/attribute.hbs" attributeId="au" attribute=data.attributes.au calc=data.calc.attributes.au}}
<div class="attribute-filler-fixed"></div>
<div class="filler"></div>
{{> "systems/midgard5/templates/sheets/character/attribute.hbs" attributeId="pa" attribute=data.attributes.pa calc=data.calc.attributes.pa}}
<div class="attribute-filler-fixed"></div>
<div class="filler"></div>
{{> "systems/midgard5/templates/sheets/character/attribute.hbs" attributeId="wk" attribute=data.attributes.wk calc=data.calc.attributes.wk}}
<div class="filler"></div>
</div>
</div>
<h3>Berechnete Werte</h3>
<div class="flexcolumn-2">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/skills/social/theft-pickpocket-bribery-brown.webp" class="flexpart-icon">{{localize "midgard5.points"}}</div>
<table>
<tbody>
<tr height = 10px></tr>
<tr>
<td>{{localize "midgard5.grace"}}</td>
<td><input name="data.gg" type="text" value="{{data.gg}}" data-dtype="Number" /></td>
<td>{{localize "midgard5.exp-overall"}}</td>
<td width="40%"><input name="data.es" type="text" value="{{data.es}}" data-dtype="Number" /></td>
</tr>
<tr>
<td>{{localize "midgard5.destiny"}}</td>
<td><input name="data.sg" type="text" value="{{data.sg}}" data-dtype="Number" /></td>
<td>{{localize "midgard5.exp-available"}}</td>
<td><input name="data.ep" type="text" value="{{data.ep}}" data-dtype="Number" /></td>
</tr>
<tr>
<td>{{localize "midgard5.luckPoints"}}</td>
<td><input name="data.gp" type="text" value="{{data.gp}}" data-dtype="Number" /></td>
<td>{{localize "midgard5.valuable"}}</td>
<td class="fixed-value">{{data.calc.stats.wealth}}</td>
</tr>
<tr height = 10px></tr>
</tbody>
</table>
</div>
</div>
<div class="flexcolumn-2">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/magic/time/arrows-circling-pink.webp" class="flexpart-icon">{{localize "midgard5.calculated-values"}}</div>
<table>
<tbody>
<tr height = 10px></tr>
<tr>
<td>{{localize "midgard5.magicUsing"}}</td>
<td><input id="data.info.magicUsing" type="checkbox" disabled="true" name="data.info.magicUsing" {{checked data.info.magicUsing}}></td>
<td>{{localize "midgard5.movementRange"}}</td>
<td><input name="data.movement" type="text" value="{{data.movement}}" data-dtype="Number" /></td>
</tr>
<tr>
<td>{{localize "midgard5.actor-lp-short"}} {{localize "midgard5.maximum"}}</td>
<td><input name="data.lp.max" type="text" value="{{data.lp.max}}" data-dtype="Number" /></td>
<td>{{localize "midgard5.actor-ap-short"}} {{localize "midgard5.maximum"}}</td>
<td><input name="data.ap.max" type="text" value="{{data.ap.max}}" data-dtype="Number" /></td>
</tr>
<tr>
<td>{{localize "midgard5.brawl"}}</td>
<td class="fixed-value">{{data.calc.stats.brawl.value}}</td>
@ -118,43 +103,44 @@
<td>{{localize "midgard5.resistanceBody"}}</td>
<td class="fixed-value">{{data.calc.stats.resistanceBody.value}}</td>
</tr>
{{#if (eq data.info.race "Zwerg")}}
<tr>
<td>{{localize "midgard5.hoard"}}</td>
<td class="fixed-value">{{data.calc.stats.hoard}}</td>
</tr>
<tr>
<td>{{localize "midgard5.hoardMin"}}</td>
<td class="fixed-value">{{data.calc.stats.hoardMin}}</td>
<td>{{localize "midgard5.hoard-next"}}</td>
<td class="fixed-value">{{data.calc.stats.hoardNext}}</td>
</tr>
{{/if}}
<tr height = 10px></tr>
</tbody>
</table>
</div>
</div>
</div>
<h3>Beschreibung</h3>
<div class="flexcolumn-1">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/skills/wounds/injury-body-pain-gray.webp" class="flexpart-icon">{{localize "midgard5.deprivations"}} & {{localize "midgard5.deprivation"}}</div>
<table>
<tbody>
<tr height = 10px></tr>
<tr>
<td>{{localize "midgard5.race"}}</td>
<td><input name="data.info.race" type="text" value="{{data.info.race}}" data-dtype="String" /></td>
<td>{{localize "midgard5.gender"}}</td>
<td><input name="data.info.gender" type="text" value="{{data.info.gender}}" data-dtype="String" /></td>
<td class="flexpart-img"><img src="/icons/consumables/food/plate-fish-bowl-bones-brown.webp" class="flexpart-icon"></td>
<td class="padding highlight">{{localize "midgard5.deprivationFood"}}</td>
<td class="center">{{data.calc.stats.deprivationFood.value}}</td>
<td class="fixed-value" style="border-right: 1px solid black;"><button class="roll-button roll-deprivationFood-button"></button></td>
<td class="flexpart-img"><img src="/icons/magic/fire/orb-lightning-sun.webp" class="flexpart-icon"></td>
<td class="padding highlight">{{localize "midgard5.deprivationHeat"}}</td>
<td class="center">{{ data.calc.stats.deprivationHeat.value}}</td>
<td class="fixed-value" style="border-right: 1px solid black;"><button class="roll-button roll-deprivationHeat-button"></button></td>
<td class="flexpart-img"><img src="/icons/magic/water/snowflake-ice-blue.webp" class="flexpart-icon"></td>
<td class="padding highlight">{{localize "midgard5.deprivationCold"}}</td>
<td class="center">{{data.calc.stats.deprivationCold.value}}</td>
<td class="fixed-value"><button class="roll-button roll-deprivationCold-button"></button></td>
</tr>
<tr>
<td>{{localize "midgard5.weight"}}</td>
<td><input name="data.info.weight" type="text" value="{{data.info.weight}}" data-dtype="String" /></td>
<td>{{localize "midgard5.height"}}</td>
<td><input name="data.info.height" type="text" value="{{data.info.height}}" data-dtype="String" /></td>
</tr>
<tr>
<td>{{localize "midgard5.shape"}}</td>
<td><input name="data.info.shape" type="text" value="{{data.info.shape}}" data-dtype="String" /></td>
<td>{{localize "midgard5.age"}}</td>
<td><input name="data.info.age" type="text" value="{{data.info.age}}" data-dtype="String" /></td>
</tr>
<tr>
<td>{{localize "midgard5.caste"}}</td>
<td><input name="data.info.caste" type="text" value="{{data.info.caste}}" data-dtype="String" /></td>
<td>{{localize "midgard5.occupation"}}</td>
<td><input name="data.info.occupation" type="text" value="{{data.info.occupation}}" data-dtype="String" /></td>
</tr>
<tr>
<td>{{localize "midgard5.origin"}}</td>
<td><input name="data.info.origin" type="text" value="{{data.info.origin}}" data-dtype="String" /></td>
<td>{{localize "midgard5.faith"}}</td>
<td><input name="data.info.faith" type="text" value="{{data.info.faith}}" data-dtype="String" /></td>
</tr>
</tbody>
</table>
{{editor content=data.description target="data.description" button=true owner=owner editable=editable}}
</div>
</div>

View File

@ -0,0 +1,262 @@
<div class="flexbox">
<div class="flexcolumn-2">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/magic/time/arrows-circling-pink.webp" class="flexpart-icon">{{localize "midgard5.calculated-values"}}</div>
<table>
<tr height = 10px></tr>
<tr>
<td>{{localize "midgard5.movementRange"}}</td>
<td class="fixed-value">{{data.calc.stats.movement.value}}</td>
<td></td>
<td class="fixed-value"></td>
</tr>
<tr>
<td>{{localize "midgard5.initiative"}}</td>
<td class="fixed-value">
{{#if (isSkillInList (localizeMidgard "anfuehren") data.calc.skills.general)}}
{{skillEwInList (localizeMidgard "anfuehren") data.calc.skills.general}}
{{else}}
{{skillEw actor._id data.skills.general.anfuehren}}
{{/if}}
</td>
<td>{{localize "midgard5.actionrank"}}</td>
<td class="fixed-value"><a class="join-combat">{{data.calc.attributes.gw.value}}</a></td>
</tr>
<tr>
<td>{{localize "midgard5.defense"}}</td>
<td class="fixed-value">{{data.calc.stats.defense.value}}</td>
<td>{{localize "midgard5.defenseBonus"}}</td>
<td class="fixed-value">{{data.calc.stats.defenseBonus.value}}</td>
</tr>
<tr>
<td>{{localize "midgard5.attackBonus"}}</td>
<td class="fixed-value">{{data.calc.stats.attackBonus.value}}</td>
<td>{{localize "midgard5.damageBonus"}}</td>
<td class="fixed-value">{{data.calc.stats.damageBonus.value}}</td>
</tr>
</table>
</div>
</div>
<div class="flexcolumn-2">
<div class="flexpart" style="padding: 0 0.5rem;">
<div class="flexpart-header">{{localize "midgard5.actionrank"}}</div>
<button class="wide-button join-combat">{{localize "midgard5.combat-join"}}</button>
<button class="wide-button ranged-combat">{{localize "midgard5.combat-ranged"}}</button>
<button class="wide-button spell-combat">{{localize "midgard5.combat-spell"}}</button>
</div>
</div>
<div class="flexcolumn-2">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/skills/melee/hand-grip-sword-white-brown.webp" class="flexpart-icon">{{localize "midgard5.attack"}}</div>
<table>
<thead>
<tr>
<th class="title"><img src="/icons/svg/eye.svg" class="table-icon"></th>
<th class="title">{{localize "TYPES.Item.weapon"}}</th>
<th class="title">{{localize "midgard5.ew"}}</th>
<th class="title">{{localize "midgard5.damage"}}</th>
<th class="title center"><img src="/systems/midgard5/assets/icons/icon/battle-gear.svg" class="table-icon"></th>
<th class="title"><img src="/icons/svg/d20.svg" class="table-icon"></th>
</tr>
</thead>
<tbody class="items-list">
{{#each data.calc.gear.weapons as |item itemId|}}
{{#if item.equipped}}
<tr data-item-id="{{itemId}}" class="item">
<td class="flexpart-img"><img src={{item.icon}} class="flexpart-icon"></td>
<td class="padding edit-item {{#if item.special}}highlight{{/if}}">{{item.label}}{{#if item.special}}(*){{/if}}</td>
<td class="fixed-value">{{item.calc.ew}}</td>
<td class="fixed-value">{{item.damageBase}}</td>
<td class="change-equipped">
{{#if item.equipped}}
<i class="fa-solid fa-circle-check"></i>
{{else}}
<i class="fa-regular fa-circle"></i>
{{/if}}
</td>
<td><button class="roll-button roll-weapon-button"></button></td>
</tr>
{{/if}}
{{/each}}
<tr data-item-id="{{itemId}}">
<td class="flexpart-img"><img src="icons/skills/melee/unarmed-punch-fist-yellow-red.webp" class="flexpart-icon"></td>
<td class="padding edit-item">{{localize "midgard5.brawl"}}</td>
<td class="fixed-value">{{data.calc.stats.brawlFw}}</td>
<td class="fixed-value">1d6 -4</td>
<td>&nbsp;</td>
<td><button class="roll-button roll-brawl-button"></button></td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th class="title"><img src="/icons/svg/eye.svg" class="table-icon"></th>
<th class="title">{{localize "TYPES.Item.kampfkunst"}}</th>
<th class="title">{{localize "midgard5.kampfkunst-variante-short"}}</th>
<th class="title">{{localize "midgard5.ew"}}</th>
<th class="title"><img src="/icons/svg/d20.svg" class="table-icon"></th>
<td><a class="title add-kampfkunst"><i class="fa-regular fa-plus"></i></a></th>
</tr>
</thead>
<tbody class="items-list">
{{#each data.calc.kampfkuenste as |item itemId|}}
<tr data-item-id="{{itemId}}" class="item">
<td class="flexpart-img"><img src={{item.icon}} class="flexpart-icon"></td>
<td class="padding edit-item">{{item.label}}</td>
<td>
{{#if item.isKido}}
<span class="spell-process">{{localize (m5concat "midgard5.kido-type-" item.type)}}</span>
{{#unless (eq item.type "finte")}}
<span class="spell-process">({{localize (m5concat "midgard5.kido-variante-" item.variante)}})</span>
{{/unless}}
{{else}}
<span class="spell-process">{{localize (m5concat "midgard5.kampfkunst-type-" item.type)}}</span>
<span class="spell-process">({{localize (m5concat "midgard5.kampfkunst-variante-" item.variante)}})</span>
{{/if}}
</td>
<td class="fixed-value">{{item.calc.ew}}</td>
<td><button class="roll-button roll-weapon-button" /></td>
<td><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</div>
<div class="flexcolumn-2">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/skills/melee/shield-block-gray-orange.webp" class="flexpart-icon">{{localize "midgard5.defense"}}</div>
<table>
<tr height = 10px></tr>
<tr>
<td class="flexpart-img"><img src="icons/magic/defensive/shield-barrier-glowing-blue.webp" class="flexpart-icon"></td>
<td class="padding edit-item highlight">{{localize "midgard5.defense"}}</td>
<td class="center">{{add data.calc.stats.defense.value data.calc.stats.defenseBonus.value}}</td>
<td class="fixed-value"><button class="roll-button roll-defense-button"></button></td>
</tr>
<tr>
<td class="flexpart-img"><img src="icons/magic/nature/elemental-plant-humanoid.webp" class="flexpart-icon"></td>
<td class="padding edit-item highlight">{{localize "midgard5.resistanceMind"}}</td>
<td class="center">{{data.calc.stats.resistanceMind.value}}</td>
<td class="fixed-value"><button class="roll-button roll-resistanceMind-button"></button></td>
</tr>
<tr>
<td class="flexpart-img"><img src="icons/magic/control/silhouette-hold-change-green.webp" class="flexpart-icon"></td>
<td class="padding edit-item highlight">{{localize "midgard5.resistanceBody"}}</td>
<td class="center">{{data.calc.stats.resistanceBody.value}}</td>
<td class="fixed-value"><button class="roll-button roll-resistanceBody-button"></button></td>
</tr>
</table>
<table>
<thead>
<tr>
<th class="title"><img src="/icons/svg/eye.svg" class="table-icon"></th>
<th class="title">{{localize "TYPES.Item.defensiveWeapon"}}</th>
<th class="title">{{localize "midgard5.ew"}}</th>
<th class="title">{{localize "midgard5.defenseBonus-short"}}</th>
<th class="title center"><img src="/systems/midgard5/assets/icons/icon/battle-gear.svg" class="table-icon"></th>
<th class="title"><img src="/icons/svg/d20.svg" class="table-icon"></th>
</tr>
</thead>
<tbody class="items-list">
{{#each data.calc.gear.defensiveWeapons as |item itemId|}}
{{#if item.equipped}}
<tr data-item-id="{{itemId}}" class="item">
<td class="flexpart-img"><img src={{item.icon}} class="flexpart-icon"></td>
<td class="padding edit-item">{{item.label}}</td>
<td class="fixed-value">{{item.calc.ew}}</td>
<td class="fixed-value">{{item.defenseBonus}}</td>
<td class="change-equipped">
{{#if item.equipped}}
<i class="fa-solid fa-circle-check"></i>
{{else}}
<i class="fa-regular fa-circle"></i>
{{/if}}
</td>
<td><button class="roll-button roll-weapon-button"></button></td>
</tr>
{{/if}}
{{/each}}
</tbody>
</table>
<table>
<thead>
<tr>
<th class="title"><img src="/icons/svg/eye.svg" class="table-icon"></th>
<th class="title">{{localize "TYPES.Item.armor"}}</th>
<th class="title">{{localize "midgard5.actor-lp-short"}}</th>
<th class="title center"><img src="/systems/midgard5/assets/icons/icon/battle-gear.svg" class="table-icon"></th>
</tr>
</thead>
<tbody class="items-list">
{{#each data.calc.gear.armor as |item itemId|}}
{{#if item.equipped}}
<tr data-item-id="{{itemId}}" class="item">
<td class="flexpart-img"><img src={{item.icon}} class="flexpart-icon"></td>
<td class="padding">{{item.label}}</td>
<td class="fixed-value">{{lpProtection}}</td>
<td class="change-equipped">
{{#if item.equipped}}
<i class="fa-solid fa-circle-check"></i>
{{else}}
<i class="fa-regular fa-circle"></i>
{{/if}}
</td>
</tr>
{{/if}}
{{/each}}
</tbody>
</table>
</div>
</div>
{{#if actor.system.info.magicUsing }}
<div class="flexcolumn-2">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/magic/symbols/star-inverted-yellow.webp" class="flexpart-icon">{{localize "TYPES.Item.spell"}}</div>
<table>
<thead>
<tr>
<th class="title">{{localize "TYPES.Item.spell"}}</th>
<th class="title">{{localize "midgard5.spell-castDuration"}}</th>
<th class="title">{{localize "midgard5.actor-ap"}}</th>
<th class="title">{{localize "midgard5.ew"}}</th>
<th class="title center"><img src="/systems/midgard5/assets/icons/icon/battle-gear.svg" class="table-icon"></th>
<th class="title"><img src="/icons/svg/d20.svg" class="table-icon"></th>
</tr>
</thead>
<tbody class="items-list">
{{#each data.calc.spells as |item itemId|}}
{{#if item.equipped}}
<tr data-item-id="{{itemId}}" class="item">
<td class="padding edit-item {{#if item.special}}highlight{{/if}}">{{item.label}}{{#if item.special}}(*){{/if}}</td>
<td class="fixed-value">{{item.castDuration}}</td>
<td class="fixed-value">{{item.ap}}</td>
<td class="fixed-value">{{item.calc.ew}}</td>
<td class="change-equipped">
{{#if item.equipped}}
<i class="fa-solid fa-circle-check"></i>
{{else}}
<i class="fa-regular fa-circle"></i>
{{/if}}
</td>
<td><button class="roll-button roll-weapon-button"></button></td>
</tr>
{{/if}}
{{/each}}
</tbody>
</table>
</div>
</div>
{{/if}}
</div>

View File

@ -0,0 +1,50 @@
<div class="flexbox">
<div class="flexcolumn-1">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/commodities/cloth/thread-spindle-white-needle.webp" class="flexpart-icon" />{{localize "midgard5.characteristics"}}</div>
<table>
<tbody>
<tr height="10px"></tr>
<tr>
<td>{{localize "midgard5.origin"}}</td>
<td><input name="data.info.origin" type="text" value="{{data.info.origin}}" data-dtype="String" /></td>
<td>{{localize "midgard5.gender"}}</td>
<td><input name="data.info.gender" type="text" value="{{data.info.gender}}" data-dtype="String" /></td>
<td>{{localize "midgard5.shape"}}</td>
<td><input name="data.info.shape" type="text" value="{{data.info.shape}}" data-dtype="String" /></td>
<td>{{localize "midgard5.age"}}</td>
<td><input name="data.info.age" type="text" value="{{data.info.age}}" data-dtype="String" /></td>
</tr>
<tr>
<td>{{localize "midgard5.weight"}}</td>
<td><input name="data.info.weight" type="text" value="{{data.info.weight}}" data-dtype="String" /></td>
<td>{{localize "midgard5.height"}}</td>
<td><input name="data.info.height" type="text" value="{{data.info.height}}" data-dtype="String" /></td>
<td>{{localize "midgard5.caste"}}</td>
<td><input name="data.info.caste" type="text" value="{{data.info.caste}}" data-dtype="String" /></td>
<td>{{localize "midgard5.faith"}}</td>
<td><input name="data.info.faith" type="text" value="{{data.info.faith}}" data-dtype="String" /></td>
</tr>
<tr height="10px"></tr>
</tbody>
</table>
</div>
</div>
<div class="flexcolumn-1">
<div class="flexpart" style="height: 250px;">
<div class="flexpart-header"><img src="icons/environment/wilderness/mine-interior-dungeon-door.webp" class="flexpart-icon" />{{localize "midgard5.description"}}</div>
<br />
<div class="biography">{{editor data.info.description target="data.info.description" button=true owner=owner editable=editable}}</div>
</div>
</div>
<div class="flexcolumn-1">
<div class="flexpart" style="height: 250px;">
<div class="flexpart-header"><img src="icons/environment/people/group.webp" class="flexpart-icon" />{{localize "midgard5.background"}}</div>
<br />
<div class="biography">{{editor data.info.background target="data.info.background" button=true owner=owner editable=editable}}</div>
</div>
</div>
</div>

View File

@ -0,0 +1,29 @@
<table>
<thead>
<tr>
<th class="title"><img src="/icons/svg/eye.svg" class="table-icon"></th>
<th class="title">{{localize "TYPES.Item.effect"}}</th>
<td><a class="title add-effect"><i class="fa-regular fa-plus"></i></a></th>
</tr>
</thead>
<tbody class="items-list">
{{#each data.calc.gear.effects as |item itemId|}}
<tr data-item-id="{{itemId}}" class="items">
<td class="flexpart-img"><img src={{item.icon}} class="flexpart-icon"></td>
<td class="padding">
<span class="edit-item">{{item.label}}</span>
{{#if item.equipped}}
<span class="spell-process">{{localize "midgard5.active"}}</span>
{{#unless (or (eq item.duration.unit "") (eq item.duration.unit "limitless"))}}
<span class="spell-process">{{item.duration.time}} {{localize (concat "midgard5.time-" item.duration.unit)}}</span>
{{/unless}}
{{/if}}
</td>
{{!--{{#unless (eq item.label "Belastung")}}--}}
<td class="fixed-value"><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
{{!--{{/unless}}--}}
</tr>
{{/each}}
</tbody>
</table>

View File

@ -1,94 +1,475 @@
<h3>{{localize "midgard5.wealthAndWeight"}}</h3>
<div class="flexbox">
<div class="flexcolumn-2">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/commodities/currency/coins-assorted-mix-copper-silver-gold.webp" class="flexpart-icon">{{localize "midgard5.currency"}}</div>
<table>
<thead>
<thead class="theader">
<tr>
<th>{{localize "ITEM.TypeWeapon"}}</th>
<th class="fixed-value">{{localize "midgard5.ew"}}</th>
<th class="fixed-value"></th>
<th class="fixed-value"></th>
<th class="title" style="text-align: center">{{localize "midgard5.currency-wealth"}}</th>
<th class="title" style="text-align: center">{{localize "midgard5.currency-gold"}}</th>
<th class="title" style="text-align: center">{{localize "midgard5.currency-silver"}}</th>
<th class="title" style="text-align: center">{{localize "midgard5.currency-copper"}}</th>
{{#if (eq data.info.race "Zwerg")}}
<th class="title" style="text-align: center">{{localize "midgard5.hoard"}}</th>
{{/if}}
</tr>
</thead>
<tbody>
{{#each data.calc.gear.weapons as |item itemId|}}
<tr data-item="{{itemId}}">
<td class="padding edit-item">{{item.label}}</td>
<td class="fixed-value">{{item.calc.ew}}</td>
<td class="fixed-value"><button class="roll-button roll-weapon-button"></button></td>
<td class="fixed-value"><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/each}}
<tr data-item="{{itemId}}">
<td class="padding edit-item">{{localize "midgard5.brawl"}}</td>
<td class="center">{{data.calc.stats.brawlEw}}</td>
<td class="fixed-value"><button class="roll-button roll-brawl-button"></button></td>
<td class="fixed-value"></td>
<tr height = 10px></tr>
<tr>
<td class="fixed-value"><input type="number" disabled="true" name="data.info.wealth" value="{{data.calc.stats.wealth}}"></td>
<td class="fixed-value"><input type="number" name="data.info.gold" value="{{data.info.gold}}"></td>
<td class="fixed-value"><input type="number" name="data.info.silver" value="{{data.info.silver}}"></td>
<td class="fixed-value"><input type="number" name="data.info.copper" value="{{data.info.copper}}"></td>
{{#if (eq data.info.race "Zwerg")}}
<td class="fixed-value"><input type="number" name="midgard5.hoard" value="{{data.calc.stats.hoard}}"></td>
{{/if}}
</tr>
</tbody>
</table>
</div>
</div>
<div class="flexcolumn-2">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/containers/bags/pack-leather-strapped-tan.webp" class="flexpart-icon">Lasten in Kilogramm</div>
<table>
<thead>
<thead class="theader">
<tr>
<th>{{localize "ITEM.TypeDefensiveWeapon"}}</th>
<th class="fixed-value">{{localize "midgard5.ew"}}</th>
<th class="fixed-value"></th>
<th class="fixed-value"></th>
<th class="title" style="text-align: center">{{localize "midgard5.load"}}</th>
<th class="title" style="text-align: center">{{localize "midgard5.heavy-load"}}</th>
<th class="title" style="text-align: center">{{localize "midgard5.load-max"}}</th>
<th class="title" style="text-align: center">{{localize "midgard5.thrust-load"}}</th>
<th class="title" style="text-align: center">{{localize "midgard5.encumbrance"}}</th>
</tr>
</thead>
<tbody>
{{#each data.calc.gear.defensiveWeapons as |item itemId|}}
<tr data-item="{{itemId}}">
<td class="padding edit-item">{{item.label}}</td>
<td class="fixed-value">{{item.calc.ew}}</td>
<td class="fixed-value"><button class="roll-button roll-weapon-button"></button></td>
<td class="fixed-value"><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
<tfoot>
<tr height = 10px></tr>
<tr>
<td class="fixed-value"><input type="number" disabled="true" name="data.info.load" value="{{data.calc.stats.load}}"></td>
<td class="fixed-value"><input type="number" disabled="true" {{#if (gt data.calc.stats.encumbrance data.calc.stats.heavyLoad) }}style="background:#FF6666"{{/if}} name="data.info.heavyLoad" value="{{data.calc.stats.heavyLoad}}"></td>
<td class="fixed-value"><input type="number" disabled="true" {{#if (gt data.calc.stats.encumbrance data.calc.stats.loadMax) }}style="background:#FF6666"{{/if}} name="data.info.loadMax" value="{{data.calc.stats.loadMax}}"></td>
<td class="fixed-value"><input type="number" disabled="true" {{#if (gt data.calc.stats.encumbrance data.calc.stats.thrustLoad) }}style="background:#FF6666"{{/if}} name="data.info.thrustLoad" value="{{data.calc.stats.thrustLoad}}"></td>
<td class="fixed-value"><input type="number" disabled="true" name="data.info.encumbrance" value="{{data.calc.stats.encumbrance}}"></td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
{{#unless (eq (count data.calc.gear.containers) 0)}}
<h3>{{localize "midgard5.itemsInContainers"}}</h3>
<div class="flexbox">
{{#each data.calc.gear.containers as |container containerId|}}
<div class="flexcolumn-2" data-container-id="{{containerId}}">
<div class="flexpart">
<div class="flexpart-header"><img src="{{container.icon}}" class="flexpart-icon">{{container.label}}</div>
<table>
<thead class="theader">
<tr>
<th class="title"><img src="/icons/svg/eye.svg" class="table-icon"></th>
<th class="title">{{localize "TYPES.Item.item"}}</th>
<th class="title center">{{localize "midgard5.item-quantity"}}</th>
<th class="title center">{{localize "midgard5.item-value"}}</th>
<th class="title center">{{localize "midgard5.item-weight"}}</th>
<th class="title center"><img src="/systems/midgard5/assets/icons/icon/battle-gear.svg" class="table-icon"></th>
<th class="title"><img src="/icons/svg/d20.svg" class="table-icon"></th>
<th class="title">&nbsp;</th>
</tr>
</thead>
<tbody class="items-list">
<tr height = 10px></tr>
{{#each ../data.calc.gear.items as |item itemId|}}
{{#if (eq item.containerId containerId)}}
<tr data-item-id="{{itemId}}" class="item">
<td class="flexpart-img"><img src={{item.icon}} class="flexpart-icon"></td>
<td class="padding">
<span class="edit-item">{{item.label}}</span>
</td>
<td>
<i class="fa fa-minus-circle quantity-decrease" style="cursor: pointer"></i>
<span>{{item.quantity}}</span>
<i class="fa fa-plus-circle quantity-increase" style="cursor: pointer"></i>
</td>
<td style="text-align: start">
{{#unless (or (eq item.value 0) (eq item.currency ""))}}
<span class="spell-process">{{item.value}} {{localize (m5concat "midgard5.currency-" item.currency)}}</span>
{{/unless}}
</td>
<td style="text-align: start">
{{#unless (or (eq item.weight "") (eq item.equipped?))}}
<span class="spell-process">{{item.weight}} kg</span>
{{/unless}}
</td>
<td class="change-equipped">
{{#if item.equipped}}
<i class="fa-solid fa-circle-check"></i>
{{else}}
<i class="fa-regular fa-circle"></i>
{{/if}}
</td>
<td>{{#if item.rollExist}}<button class="roll-button roll-consumable-item"></button>{{/if}}</td>
<td><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/if}}
{{/each}}
{{#each ../data.calc.gear.weapons as |item itemId|}}
{{#if (eq item.containerId containerId)}}
<tr data-item-id="{{itemId}}" class="item">
<td class="flexpart-img"><img src={{item.icon}} class="flexpart-icon"></td>
<td class="padding">
<span class="edit-item">{{item.label}}</span>
</td>
<td></td>
<td style="text-align: start">
{{#unless (or (eq item.value 0) (eq item.currency ""))}}
<span class="spell-process">{{item.value}} {{localize (m5concat "midgard5.currency-" item.currency)}}</span>
{{/unless}}
</td>
<td style="text-align: start">
{{#unless (or (eq item.weight "") (eq item.equipped?))}}
<span class="spell-process">{{item.weight}} kg</span>
{{/unless}}
</td>
<td class="change-equipped">
{{#if item.equipped}}
<i class="fa-solid fa-circle-check"></i>
{{else}}
<i class="fa-regular fa-circle"></i>
{{/if}}
</td>
<td>{{#if item.rollExist}}<button class="roll-button roll-consumable-item"></button>{{/if}}</td>
<td><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/if}}
{{/each}}
{{#each ../data.calc.gear.defensiveWeapons as |item itemId|}}
{{#if (eq item.containerId containerId)}}
<tr data-item-id="{{itemId}}" class="item">
<td class="flexpart-img"><img src={{item.icon}} class="flexpart-icon"></td>
<td class="padding">
<span class="edit-item">{{item.label}}</span>
</td>
<td></td>
<td style="text-align: start">
{{#unless (or (eq item.value 0) (eq item.currency ""))}}
<span class="spell-process">{{item.value}} {{localize (m5concat "midgard5.currency-" item.currency)}}</span>
{{/unless}}
</td>
<td style="text-align: start">
{{#unless (or (eq item.weight "") (eq item.equipped?))}}
<span class="spell-process">{{item.weight}} kg</span>
{{/unless}}
</td>
<td class="change-equipped">
{{#if item.equipped}}
<i class="fa-solid fa-circle-check"></i>
{{else}}
<i class="fa-regular fa-circle"></i>
{{/if}}
</td>
<td>{{#if item.rollExist}}<button class="roll-button roll-consumable-item"></button>{{/if}}</td>
<td><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/if}}
{{/each}}
{{#each ../data.calc.gear.armor as |item itemId|}}
{{#if (eq item.containerId containerId)}}
<tr data-item-id="{{itemId}}" class="item">
<td class="flexpart-img"><img src={{item.icon}} class="flexpart-icon"></td>
<td class="padding">
<span class="edit-item">{{item.label}}</span>
</td>
<td></td>
<td style="text-align: start">
{{#unless (or (eq item.value 0) (eq item.currency ""))}}
<span class="spell-process">{{item.value}} {{localize (m5concat "midgard5.currency-" item.currency)}}</span>
{{/unless}}
</td>
<td style="text-align: start">
{{#unless (or (eq item.weight "") (eq item.equipped?))}}
<span class="spell-process">{{item.weight}} kg</span>
{{/unless}}
</td>
<td class="change-equipped">
{{#if item.equipped}}
<i class="fa-solid fa-circle-check"></i>
{{else}}
<i class="fa-regular fa-circle"></i>
{{/if}}
</td>
<td>{{#if item.rollExist}}<button class="roll-button roll-consumable-item"></button>{{/if}}</td>
<td><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/if}}
{{/each}}
</tbody>
</table>
</div>
</div>
{{/each}}
</div>
{{/unless}}
<h3>
{{localize "midgard5.allItems"}}
<input id="data.info.showAllItems" class="checkbox" type="checkbox" name="data.info.showAllItems" {{checked data.info.showAllItems}} style="float: right;">
<label for="data.info.showAllItems" style="font-size: small; font-weight: normal; font-style: italic; float: right;">{{localize "midgard5.showAll"}}&nbsp;</label>
</h3>
<div class="flexbox">
<div class="flexcolumn-2">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/containers/chest/chest-simple-box-brown.webp" class="flexpart-icon">{{localize "TYPES.Item.container"}}</div>
<table>
<thead class="theader">
<tr>
<th class="title"><img src="/icons/svg/eye.svg" class="table-icon"></th>
<th class="title">{{localize "TYPES.Item.container"}}</th>
<th class="title center">{{localize "midgard5.item-value"}}</th>
<th class="title center">{{localize "midgard5.item-weight"}}</th>
<th class="title center">{{localize "midgard5.capacity"}}</th>
<th class="title center"><img src="/systems/midgard5/assets/icons/icon/battle-gear.svg" class="table-icon"></th>
<th class="title"><img src="/icons/svg/d20.svg" class="table-icon"></th>
<th><a class="title add-container"><i class="fa-regular fa-plus"></i></a></th>
</tr>
</thead>
<tbody class="items-list">
<tr height = 10px></tr>
{{#each data.calc.gear.containers as |item itemId|}}
<tr data-item-id="{{itemId}}" class="item">
<td class="flexpart-img"><img src={{item.icon}} class="flexpart-icon"></td>
<td class="padding">
<span class="edit-item">{{item.label}}</span>
</td>
<td style="text-align: start">
{{#unless (or (eq item.value 0) (eq item.currency ""))}}
<span class="spell-process">{{item.value}} {{localize (m5concat "midgard5.currency-" item.currency)}}</span>
{{/unless}}
</td>
<td style="text-align: start">
{{#unless (or (eq item.weight 0) (eq item.equipped?))}}
<span class="spell-process">{{item.weight}}kg</span>
{{/unless}}
</td>
<td style="text-align: start">
{{#unless (eq item.capacity 0)}}
<span class="spell-process"{{#if (gt item.weight item.capacity) }}style="background:#FF6666"{{/if}}>{{item.capacity}}kg</span>
{{/unless}}
</td>
<td class="change-equipped">
{{#if item.equipped}}
<i class="fa-solid fa-circle-check"></i>
{{else}}
<i class="fa-regular fa-circle"></i>
{{/if}}
</td>
<td>{{#if item.rollExist}}<button class="roll-button roll-consumable-item"></button>{{/if}}</td>
<td><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</div>
<div class="flexcolumn-2">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/tools/hand/scale-balances-merchant-brown.webp" class="flexpart-icon">{{localize "midgard5.gear"}}</div>
<table>
<thead>
<thead class="theader">
<tr>
<th>{{localize "ITEM.TypeArmor"}}</th>
<th class="fixed-value">{{localize "midgard5.actor-lp-short"}}</th>
<th class="fixed-value">{{localize "midgard5.actor-ap-short"}}</th>
<th class="fixed-value">{{localize "midgard5.attackBonus-short"}}</th>
<th class="fixed-value">{{localize "midgard5.defenseBonus-short"}}</th>
<th class="fixed-value">B</th>
<th class="fixed-value">Gw</th>
<th class="fixed-value"></th>
<th class="title"><img src="/icons/svg/eye.svg" class="table-icon"></th>
<th class="title">{{localize "TYPES.Item.item"}}</th>
<th class="title center">{{localize "midgard5.item-quantity"}}</th>
<th class="title center">{{localize "midgard5.item-value"}}</th>
<th class="title center">{{localize "midgard5.item-weight"}}</th>
<th class="title"><img src="/systems/midgard5/assets/icons/icon/battle-gear.svg" class="table-icon"></th>
<th class="title"><img src="/icons/svg/d20.svg" class="table-icon"></th></th>
<th><a class="title add-item"><i class="fa-regular fa-plus"></i></a></th>
</tr>
</thead>
<tbody>
{{#each data.calc.gear.armor as |item itemId|}}
<tr data-item="{{itemId}}">
<td class="padding edit-item">{{item.label}}</td>
<td class="fixed-value">{{actorItemValue ../actor._id itemId "lpProtection"}}</td>
<td class="fixed-value">{{actorItemValue ../actor._id itemId "apProtection"}}</td>
<td class="fixed-value">{{actorItemValue ../actor._id itemId "stats.attackBonus"}}</td>
<td class="fixed-value">{{actorItemValue ../actor._id itemId "stats.defenseBonus"}}</td>
<td class="fixed-value">{{actorItemValue ../actor._id itemId "stats.movementBonus"}}</td>
<td class="fixed-value">{{actorItemValue ../actor._id itemId "attributeMod.gw"}}</td>
<td class="fixed-value"><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/each}}
</tbody>
</table>
<table>
<thead>
<tr>
<th>{{localize "ITEM.TypeItem"}}</th>
<th></th>
</tr>
</thead>
<tbody>
<tbody class="items-list">
<tr height = 10px></tr>
{{#each data.calc.gear.items as |item itemId|}}
<tr data-item="{{itemId}}">
<td class="padding edit-item">{{item.label}}</td>
<td class="fixed-value"><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
{{#if (or ../data.info.showAllItems (eq item.containerId ""))}}
<tr data-item-id="{{itemId}}" class="item">
<td class="flexpart-img"><img src={{item.icon}} class="flexpart-icon"></td>
<td class="padding">
<span class="edit-item">{{item.label}}</span>
</td>
<td>
<i class="fa fa-minus-circle quantity-decrease" style="cursor: pointer"></i>
<span>{{item.quantity}}</span>
<i class="fa fa-plus-circle quantity-increase" style="cursor: pointer"></i>
</td>
<td style="text-align: start">
{{#unless (or (eq item.value 0) (eq item.currency ""))}}
<span class="spell-process">{{item.value}} {{localize (m5concat "midgard5.currency-" item.currency)}}</span>
{{/unless}}
</td>
<td style="text-align: start">
{{#unless (or (eq item.weight "") (eq item.equipped?))}}
<span class="spell-process">{{item.weight}} kg</span>
{{/unless}}
</td>
<td class="change-equipped">
{{#if item.equipped}}
<i class="fa-solid fa-circle-check"></i>
{{else}}
<i class="fa-regular fa-circle"></i>
{{/if}}
</td>
<td>{{#if item.rollExist}}<button class="roll-button roll-consumable-item"></button>{{/if}}</td>
<td><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/if}}
{{/each}}
</tbody>
</table>
</div>
</div>
<div class="flexcolumn-2">
<div class="flexpart">
<div class="flexpart-header">
<img src="icons/weapons/swords/sword-guard-engraved-worn.webp" class="flexpart-icon">{{localize "midgard5.weapons"}}</div>
<table>
<thead>
<tr>
<th class="title"><img src="/icons/svg/eye.svg" class="table-icon"></th>
<th class="title">{{localize "TYPES.Item.weapon"}}</th>
<th class="title center">{{localize "midgard5.item-value"}}</th>
<th class="title center">{{localize "midgard5.item-weight"}}</th>
<th class="title"><img src="/systems/midgard5/assets/icons/icon/battle-gear.svg" class="table-icon"></th>
<th><a class="title add-weapon"><i class="fa-regular fa-plus"></i></a></th>
</tr>
</thead>
<tbody class="items-list">
{{#each data.calc.gear.weapons as |item itemId|}}
{{#if (or ../data.info.showAllItems (eq item.containerId ""))}}
<tr data-item-id="{{itemId}}" class="item">
<td class="flexpart-img"><img src={{item.icon}} class="flexpart-icon"></td>
<td class="padding edit-item">{{item.label}}</td>
<td style="text-align: start">
{{#unless (or (eq item.value 0) (eq item.currency ""))}}
<span class="spell-process">{{item.value}} {{localize (m5concat "midgard5.currency-" item.currency)}}</span>
{{/unless}}
</td>
<td style="text-align: start">
{{#unless (or (eq item.weight "") (eq item.equipped?))}}
<span class="spell-process">{{item.weight}} kg</span>
{{/unless}}
</td>
<td class="change-equipped">
{{#if item.equipped}}
<i class="fa-solid fa-circle-check"></i>
{{else}}
<i class="fa-regular fa-circle"></i>
{{/if}}
</td>
<td><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/if}}
{{/each}}
</tbody>
</table>
</div>
</div>
<div class="flexcolumn-2">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/equipment/shield/heater-wooden-brown-axe.webp" class="flexpart-icon">{{localize "midgard5.defensive-weapons"}}</div>
<table>
<thead>
<tr>
<th class="title"><img src="/icons/svg/eye.svg" class="table-icon"></th>
<th class="title">{{localize "TYPES.Item.defensiveWeapon"}}</th>
<th class="title center">{{localize "midgard5.item-value"}}</th>
<th class="title center">{{localize "midgard5.item-weight"}}</th>
<th class="title"><img src="/systems/midgard5/assets/icons/icon/battle-gear.svg" class="table-icon"></th>
<th><a class="title add-defensiveWeapon"><i class="fa-regular fa-plus"></i></a></th>
</tr>
</thead>
<tbody class="items-list">
{{#each data.calc.gear.defensiveWeapons as |item itemId|}}
{{#if (or ../data.info.showAllItems (eq item.containerId ""))}}
<tr data-item-id="{{itemId}}" class="item">
<td class="flexpart-img"><img src={{item.icon}} class="flexpart-icon"></td>
<td class="padding edit-item">{{item.label}}</td>
<td style="text-align: start">
{{#unless (or (eq item.value 0) (eq item.currency ""))}}
<span class="spell-process">{{item.value}} {{localize (m5concat "midgard5.currency-" item.currency)}}</span>
{{/unless}}
</td>
<td style="text-align: start">
{{#unless (or (eq item.weight "") (eq item.equipped?))}}
<span class="spell-process">{{item.weight}} kg</span>
{{/unless}}
</td>
<td class="change-equipped">
{{#if item.equipped}}
<i class="fa-solid fa-circle-check"></i>
{{else}}
<i class="fa-regular fa-circle"></i>
{{/if}}
</td>
<td><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/if}}
{{/each}}
</tbody>
</table>
</div>
</div>
<div class="flexcolumn-2">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/equipment/hand/gauntlet-armored-steel-grey.webp" class="flexpart-icon">{{localize "midgard5.armor"}}</div>
<table>
<thead>
<tr>
<th class="title"><img src="/icons/svg/eye.svg" class="table-icon"></th>
<th class="title">{{localize "TYPES.Item.armor"}}</th>
<th class="title center">{{localize "midgard5.item-value"}}</th>
<th class="title center">{{localize "midgard5.item-weight"}}</th>
<th class="title"><img src="/systems/midgard5/assets/icons/icon/battle-gear.svg" class="table-icon"></th>
<th><a class="title add-armor"><i class="fa-regular fa-plus"></i></a></th>
</tr>
</thead>
<tbody class="items-list">
{{#each data.calc.gear.armor as |item itemId|}}
{{#if (or ../data.info.showAllItems (eq item.containerId ""))}}
<tr data-item-id="{{itemId}}" class="item">
<td class="flexpart-img"><img src={{item.icon}} class="flexpart-icon"></td>
<td class="padding edit-item">{{item.label}}</td>
<td style="text-align: start">
{{#unless (or (eq item.value 0) (eq item.currency ""))}}
<span class="spell-process">{{item.value}} {{localize (m5concat "midgard5.currency-" item.currency)}}</span>
{{/unless}}
</td>
<td style="text-align: start">
{{#unless (or (eq item.weight "") (eq item.equipped?))}}
<span class="spell-process">{{item.weight}} kg</span>
{{/unless}}
</td>
<td class="change-equipped">
{{#if item.equipped}}
<i class="fa-solid fa-circle-check"></i>
{{else}}
<i class="fa-regular fa-circle"></i>
{{/if}}
</td>
<td><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/if}}
{{/each}}
</tbody>
</table>
</div>
</div>
</div>

View File

@ -1,7 +1,123 @@
<form class="actor-sheet {{cssClass}}" autocomplete="off">
<header class="sheet-header">
<header class="flexbox" style="background-color: beige; padding: 5px; border: 2px solid black;">
<!-- Logo -->
<div class="flexcolumn-5" style="height: 200px;">
<img class="profile-img" src="/systems/midgard5/assets/icons/backgrounds/bg1.webp" alt="Midgard">
</div>
<!-- Name, Class, Level, Race, Occupation -->
<div class="flexcolumn-2" style="margin:0px 5px 0px 5px;">
<table class="bordered">
<tr>
<td >{{localize "midgard5.actor-name"}}</td>
<td colspan="3"><input name="name" type="text" value="{{actor.name}}" data-dtype="String" /></td>
</tr>
<tr>
<td >{{localize "midgard5.class"}}</td>
<td >
{{#each data.info.class as |class id|}}
<div class="chip" data-item-id="{{id}}">
<a class="edit-item" name="data.info.class" type="text" disabled="true" value="" data-dtype="String">{{class}}</a>
<span><a class="closebtn item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></span>
</div>
{{/each}}
</td>
<td >{{localize "midgard5.level"}}</td>
<td>{{data.calc.level}}</td>
</table>
<table style="font-weight: bold;">
<tr height = 10px></tr>
<tr>
<td >
<input list="races" type="search" name="data.info.race" value="{{data.info.race}}" />
<datalist id="races">
<option value="Mensch">
<option value="Elf">
<option value="Gnom">
<option value="Halbling">
<option value="Zwerg">
</datalist>
</td>
<td ><input name="data.info.occupation" type="text" value="{{data.info.occupation}}" data-dtype="String" /></td>
</tr>
<tr>
<td style="text-align: center; font-size: small">{{localize "midgard5.race"}}</td>
<td style="text-align: center; font-size: small">{{localize "midgard5.occupation"}}</td>
</tr>
</table>
<table style="width: 100%;">
<tr>
<td class="attribute-value roll-attribute-button" data-attribute="st" data-value="{{data.calc.attributes.st.value}}">{{data.calc.attributes.st.value}}</td>
<td class="attribute-value roll-attribute-button" data-attribute="gs" data-value="{{data.calc.attributes.gs.value}}">{{data.calc.attributes.gs.value}}</td>
<td class="attribute-value roll-attribute-button" data-attribute="gw" data-value="{{data.calc.attributes.gw.value}}">{{data.calc.attributes.gw.value}}</td>
<td class="attribute-value roll-attribute-button" data-attribute="ko" data-value="{{data.calc.attributes.ko.value}}">{{data.calc.attributes.ko.value}}</td>
<td class="attribute-value roll-attribute-button" data-attribute="in" data-value="{{data.calc.attributes.in.value}}">{{data.calc.attributes.in.value}}</td>
<td class="attribute-value roll-attribute-button" data-attribute="zt" data-value="{{data.calc.attributes.zt.value}}">{{data.calc.attributes.zt.value}}</td>
<td class="attribute-value roll-attribute-button" data-attribute="au" data-value="{{data.calc.attributes.au.value}}">{{data.calc.attributes.au.value}}</td>
<td class="attribute-value roll-attribute-button" data-attribute="pa" data-value="{{data.calc.attributes.pa.value}}">{{data.calc.attributes.pa.value}}</td>
<td class="attribute-value roll-attribute-button" data-attribute="wk" data-value="{{data.calc.attributes.wk.value}}">{{data.calc.attributes.wk.value}}</td>
<td class="attribute-value roll-attribute-button" data-attribute="git" data-value="{{data.calc.stats.poisonResistance.value}}">{{data.calc.stats.poisonResistance.value}}</td>
</tr>
<tr>
<td class="attribute">{{localize "midgard5.actor-st"}}</td>
<td class="attribute">{{localize "midgard5.actor-gs"}}</td>
<td class="attribute">{{localize "midgard5.actor-gw"}}</td>
<td class="attribute">{{localize "midgard5.actor-ko"}}</td>
<td class="attribute">{{localize "midgard5.actor-in"}}</td>
<td class="attribute">{{localize "midgard5.actor-zt"}}</td>
<td class="attribute">{{localize "midgard5.actor-au"}}</td>
<td class="attribute">{{localize "midgard5.actor-pa"}}</td>
<td class="attribute">{{localize "midgard5.actor-wk"}}</td>
<td class="attribute">{{localize "midgard5.actor-git"}}</td>
</tr>
</table>
</div>
<!-- Profilbild -->
<div class="flexcolumn-5" style="height: 200px;text-align: center;" >
<img class="profile-img" src="{{actor.img}}" data-edit="img" title="{{actor.name}}" />
<h1 class="charname"><input name="name" type="text" value="{{actor.name}}" placeholder="Name" /></h1>
</div>
<!-- LP + AP -->
<div class="flexcolumn-1">
<table>
<tr>
<td><b>{{localize "midgard5.actor-lp-short"}}</b></td>
<td colspan="9">
<div class="health-bar">
<input name="data.lp.value" type="text" value="{{data.lp.value}}" data-dtype="Number" />
{{#times data.lp.max}}
{{#if (lt this ../data.lp.value)}}
<div class="lp-bar-item update-lp" data-value="{{this}}"></div>
{{else}}
<div class="lp-bar-item-empty update-lp" data-value="{{this}}"></div>
{{/if}}
{{/times}}
<div class="max-value">{{data.lp.max}}</div>
</div>
</td>
</tr>
<tr>
<td><b>{{localize "midgard5.actor-ap-short"}}</b></td>
<td colspan="9">
<div class="health-bar">
<input name="data.ap.value" type="text" value="{{data.ap.value}}" data-dtype="Number" />
{{#times data.ap.max}}
{{#if (lt this ../data.ap.value)}}
<div class="ap-bar-item update-ap" data-value="{{this}}"></div>
{{else}}
<div class="ap-bar-item-empty update-ap" data-value="{{this}}"></div>
{{/if}}
{{/times}}
<div class="max-value">{{data.ap.max}}</div>
</div>
</td>
</tr>
</table>
</div>
</header>
{{!-- Character Sheet Navigation --}}
@ -9,7 +125,12 @@
<a class="item active" data-tab="base_values">{{ localize "midgard5.base_values" }}</a>
<a class="item" data-tab="skills">{{ localize "midgard5.skills" }}</a>
<a class="item" data-tab="gear">{{ localize "midgard5.gear" }}</a>
<a class="item" data-tab="combat">{{ localize "midgard5.combat" }}</a>
{{#if actor.system.info.magicUsing }}
<a class="item" data-tab="spells">{{ localize "midgard5.spells" }}</a>
{{/if}}
<a class="item" data-tab="effects">{{ localize "midgard5.effects" }}</a>
<a class="item" data-tab="description">{{ localize "midgard5.description" }}</a>
</nav>
<section class="sheet-content">
@ -18,17 +139,28 @@
{{> "systems/midgard5/templates/sheets/character/base_values.hbs"}}
</div>
<div class="tab base_values flexcol" data-group="primary" data-tab="skills">
<div class="tab skills flexcol" data-group="primary" data-tab="skills">
{{> "systems/midgard5/templates/sheets/character/skills.hbs"}}
</div>
<div class="tab base_values flexcol" data-group="primary" data-tab="gear">
<div class="tab gear flexcol" data-group="primary" data-tab="gear">
{{> "systems/midgard5/templates/sheets/character/gear.hbs"}}
</div>
<div class="tab base_values flexcol" data-group="primary" data-tab="spells">
<div class="tab combat flexcol" data-group="primary" data-tab="combat">
{{> "systems/midgard5/templates/sheets/character/combat.hbs"}}
</div>
<div class="tab spells flexcol" data-group="primary" data-tab="spells">
{{> "systems/midgard5/templates/sheets/character/spells.hbs"}}
</div>
<div class="tab effects flexcol" data-group="primary" data-tab="effects">
{{> "systems/midgard5/templates/sheets/character/effects.hbs"}}
</div>
<div class="tab description flexcol" data-group="primary" data-tab="description">
{{> "systems/midgard5/templates/sheets/character/description.hbs"}}
</div>
</section>
</form>

View File

@ -1,134 +1,177 @@
<table>
<thead>
<tr>
<th>{{localize "midgard5.learned-skill"}}</th>
<th>{{localize "midgard5.fw"}}</th>
<th>{{localize "midgard5.bonus"}}</th>
<th>{{localize "midgard5.ew"}}</th>
<th>{{localize "midgard5.pp-short"}}</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{{#each data.calc.skills.general as |skill skillId|}}
<tr data-item="{{skillId}}">
<td class="padding edit-item">{{skill.label}}</td>
<td class="fixed-value">{{skill.fw}}</td>
<td class="fixed-value">{{skill.calc.bonus}}</td>
<td class="fixed-value">{{skill.calc.ew}}</td>
<td class="fixed-value">{{skill.pp}}</td>
<td class="fixed-value"><button class="roll-button roll-learned-button"></button></td>
<td class="fixed-value"><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/each}}
</tbody>
</table>
<div class="flexbox">
<div class="flexcolumn-2">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/creatures/eyes/human-single-brown.webp" class="flexpart-icon">{{localize "midgard5.innate-abilities"}}</div>
<table>
<thead>
<tr>
<th>{{localize "midgard5.language"}}</th>
<th>{{localize "midgard5.fw"}}</th>
<th>{{localize "midgard5.bonus"}}</th>
<th>{{localize "midgard5.ew"}}</th>
<th>{{localize "midgard5.pp-short"}}</th>
<th></th>
<th></th>
<th class="title"><img src="/icons/svg/eye.svg" class="table-icon"></th>
<th class="title">{{localize "midgard5.innate-ability"}}</th>
<th class="title">{{localize "midgard5.fw"}}</th>
<th class="title">{{localize "midgard5.bonus"}}</th>
<th class="title">{{localize "midgard5.ew"}}</th>
<th class="title"><img src="/icons/svg/d20.svg" class="table-icon"></th>
<th><a class="title add-innate-skill"><i class="fa-regular fa-plus"></i></a></th>
</tr>
</thead>
<tbody>
{{#each data.calc.skills.language as |skill skillId|}}
<tr data-item="{{skillId}}">
<td class="padding edit-item">{{skill.label}}</td>
<td class="fixed-value">{{skill.fw}}</td>
<td class="fixed-value">{{skill.calc.bonus}}</td>
<td class="fixed-value">{{skill.calc.ew}}</td>
<td class="fixed-value">{{skill.pp}}</td>
<td class="fixed-value"><button class="roll-button roll-learned-button"></button></td>
<td class="fixed-value"><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/each}}
</tbody>
</table>
<table>
<thead>
<tr>
<th>{{localize "midgard5.innate-ability"}}</th>
<th>{{localize "midgard5.fw"}}</th>
<th>{{localize "midgard5.bonus"}}</th>
<th>{{localize "midgard5.ew"}}</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tbody class="items-list">
{{#each data.calc.skills.innate as |skill skillId|}}
<tr data-item="{{skillId}}">
<tr data-item-id="{{skillId}}" class="item">
<td class="flexpart-img"><img src={{skill.icon}} class="flexpart-icon"></td>
<td class="padding edit-item">{{skill.label}}</td>
<td class="fixed-value">{{skill.fw}}</td>
<td class="fixed-value">{{skill.calc.bonus}}</td>
<td class="fixed-value">{{skill.calc.ew}}</td>
<td class="fixed-value"><button class="roll-button roll-learned-button"></button></td>
<td class="fixed-value"><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
<td><button class="roll-button roll-learned-button"></button></td>
<td><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/each}}
</tbody>
</table>
</div>
<div class="flexpart">
<div class="flexpart-header"><img src="icons/skills/trades/construction-mason-stonecutter-sculpture.webp" class="flexpart-icon">{{localize "midgard5.learned-skills"}}</div>
<table>
<thead>
<tr>
<th>{{localize "midgard5.weapon-skill"}}</th>
<th>{{localize "midgard5.fw"}}</th>
<th>{{localize "midgard5.bonus"}}</th>
<th>{{localize "midgard5.ew"}}</th>
<th>{{localize "midgard5.pp-short"}}</th>
<th></th>
<th></th>
<th class="title">{{localize "midgard5.learned-skill"}}</th>
<th class="title">{{localize "midgard5.fw"}}</th>
<th class="title">{{localize "midgard5.bonus"}}</th>
<th class="title">{{localize "midgard5.ew"}}</th>
<th class="title">{{localize "midgard5.pp-short"}}</th>
<th class="title"><img src="/icons/svg/d20.svg" class="table-icon"></th>
<th><a class="title add-general-skill"><i class="fa-regular fa-plus"></i></a></th>
</tr>
</thead>
<tbody>
{{#each data.calc.skills.combat as |skill skillId|}}
<tr data-item="{{skillId}}">
<tbody class="items-list">
{{#each data.calc.skills.general as |skill skillId|}}
<tr data-item-id="{{skillId}}" class="item">
<td class="padding edit-item">{{skill.label}}</td>
<td class="fixed-value">{{skill.fw}}</td>
<td>
<i class="fa fa-minus-circle fw-decrease" style="cursor: pointer"></i>
<span>{{skill.fw}}</span>
<i class="fa fa-plus-circle fw-increase" style="cursor: pointer"></i>
</td>
<td class="fixed-value">{{skill.calc.bonus}}</td>
<td class="fixed-value">{{skill.calc.ew}}</td>
<td class="fixed-value">{{skill.pp}}</td>
<td class="fixed-value"><button class="roll-button roll-learned-button"></button></td>
<td class="fixed-value"><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
<td><button class="roll-button roll-learned-button"></button></td>
<td><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/each}}
</tbody>
</table>
</div>
<div class="flexpart">
<div class="flexpart-header"><img src="icons/weapons/swords/swords-short.webp" class="flexpart-icon">{{localize "midgard5.weapon-skills"}}</div>
<table>
<thead>
<tr>
<th></th>
<th>{{localize "midgard5.unlearned-skill"}}</th>
<th>{{localize "midgard5.fw"}}</th>
<th>{{localize "midgard5.bonus"}}</th>
<th>{{localize "midgard5.ew"}}</th>
<th>{{localize "midgard5.pp-short"}}</th>
<th></th>
<th></th>
<th class="title"><img src="/icons/svg/eye.svg" class="table-icon"></th>
<th class="title">{{localize "midgard5.weapon-skill"}}</th>
<th class="title">{{localize "midgard5.fw"}}</th>
<th class="title">{{localize "midgard5.bonus"}}</th>
<th class="title">{{localize "midgard5.ew"}}</th>
<th class="title">{{localize "midgard5.pp-short"}}</th>
<th class="title"><img src="/icons/svg/d20.svg" class="table-icon"></th>
<th><a class="title add-combat-skill"><i class="fa-regular fa-plus"></i></th>
</tr>
</thead>
<tbody class="items-list">
{{#each data.calc.skills.combat as |skill skillId|}}
<tr data-item-id="{{skillId}}" class="item">
<td class="flexpart-img"><img src={{skill.icon}} class="flexpart-icon"></td>
<td class="padding edit-item">{{skill.label}}</td>
<td>
<i class="fa fa-minus-circle fw-decrease" style="cursor: pointer"></i>
<span>{{skill.fw}}</span>
<i class="fa fa-plus-circle fw-increase" style="cursor: pointer"></i>
</td>
<td class="fixed-value">{{skill.calc.bonus}}</td>
<td class="fixed-value">{{skill.calc.ew}}</td>
<td class="fixed-value">{{skill.pp}}</td>
<td><button class="roll-button roll-learned-button"></button></td>
<td><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/each}}
</tbody>
</table>
</div>
<div class="flexpart">
<div class="flexpart-header"><img src="icons/sundries/scrolls/scroll-runed-worn-tan.webp" class="flexpart-icon">{{localize "midgard5.languages"}} & {{localize "midgard5.writings"}}</div>
<table>
<thead>
<tr>
<th class="title"><img src="/icons/svg/eye.svg" class="table-icon"></th>
<th class="title">{{localize "midgard5.language"}}</th>
<th class="title">{{localize "midgard5.fw"}}</th>
<th class="title">{{localize "midgard5.bonus"}}</th>
<th class="title">{{localize "midgard5.ew"}}</th>
<th class="title">{{localize "midgard5.pp-short"}}</th>
<th class="title"><img src="/icons/svg/d20.svg" class="table-icon"></th>
<th><a class="title add-language-skill"><i class="fa-regular fa-plus"></i></a></th>
</tr>
</thead>
<tbody class="items-list">
{{#each data.calc.skills.language as |skill skillId|}}
<tr data-item-id="{{skillId}}" class="item">
<td class="flexpart-img"><img src={{skill.icon}} class="flexpart-icon"></td>
<td class="padding edit-item">{{skill.label}}</td>
<td>
<i class="fa fa-minus-circle fw-decrease" style="cursor: pointer"></i>
<span>{{skill.fw}}</span>
<i class="fa fa-plus-circle fw-increase" style="cursor: pointer"></i>
</td>
<td class="fixed-value">{{skill.calc.bonus}}</td>
<td class="fixed-value">{{skill.calc.ew}}</td>
<td class="fixed-value">{{skill.pp}}</td>
<td><button class="roll-button roll-learned-button"></button></td>
<td><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</div>
<div class="flexcolumn-2">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/sundries/gaming/dice-pair-white-green.webp" class="flexpart-icon">{{localize "midgard5.unlearned-skills"}}</div>
<input id="data.info.showUnlearned" class="checkbox" type="checkbox" name="data.info.showUnlearned" {{checked data.info.showUnlearned}} style="float: right;">
<label for="data.info.showUnlearned" style="font-size: small; font-weight: normal; font-style: italic; float: right;">{{localize "midgard5.showUnlearned"}}&nbsp;</label>
<table>
<thead>
<tr>
<th class="title"></th>
<th class="title">{{localize "midgard5.unlearned-skill"}}</th>
<th class="title">{{localize "midgard5.fw"}}</th>
<th class="title">{{localize "midgard5.bonus"}}</th>
<th class="title">{{localize "midgard5.ew"}}</th>
<th class="title"><img src="/icons/svg/d20.svg" class="table-icon"></th>
</tr>
</thead>
<tbody>
{{#unless (not data.info.showUnlearned)}}
{{#each data.skills.general as |skill key|}}
{{#unless (isSkillInList (localizeMidgard key) ../actor.system.calc.skills.general) }}
<tr data-skill="{{key}}">
<td><button class="learn-button">{{localize "midgard5.learn"}}</button></td>
<td class="padding">{{localizeMidgard key}}</td>
<td class="padding" style="font-style: italic;">{{localizeMidgard key}}</td>
<td class="fixed-value">{{skill.fw}}</td>
<td class="fixed-value">{{skillBonus ../actor._id skill}}</td>
<td class="fixed-value">{{skillEw ../actor._id skill}}</td>
<td class="fixed-value"><input name="data.skills.general.{{key}}.pp" type="text" value="{{skill.pp}}" data-dtype="Number" /></td>
<td class="fixed-value"><button class="roll-button roll-general-button"></button></td>
<td class="fixed-value"></td>
<td><button class="roll-button roll-general-button"></button></td>
</tr>
{{/unless}}
{{/each}}
{{/unless}}
</tbody>
</table>
</div>
</div>
</div>

View File

@ -1,23 +1,108 @@
<div class="flexbox">
<div class="flexcolumn-1">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/magic/symbols/star-inverted-yellow.webp" class="flexpart-icon">{{localize "midgard5.spellCasting"}}</div>
<table>
<tr height = 10px></tr>
<tr>
<td bgcolor="#eaead7" class="padding edit-item highlight" >{{localize "midgard5.spellCasting"}}</td>
<td bgcolor="#eaead7" class="center">{{data.calc.stats.spellCasting.value}}</td>
<td bgcolor="#eaead7" class="fixed-value" style="border-right: 1px solid black;"><button class="roll-button roll-cleanSpell-button" /></td>
<td class="padding edit-item highlight">{{localize "midgard5.defense"}}</td>
<td class="center">{{add data.calc.stats.defense.value data.calc.stats.defenseBonus.value}}</td>
<td class="fixed-value" style="border-right: 1px solid black;"><button class="roll-button roll-defense-button"></button></td>
<td bgcolor="#eaead7" class="padding edit-item highlight">{{localize "midgard5.resistanceMind"}}</td>
<td bgcolor="#eaead7" class="center">{{data.calc.stats.resistanceMind.value}}</td>
<td bgcolor="#eaead7" class="fixed-value" style="border-right: 1px solid black;"><button class="roll-button roll-resistanceMind-button"></button></td>
<td class="padding edit-item highlight">{{localize "midgard5.resistanceBody"}}</td>
<td class="center">{{data.calc.stats.resistanceBody.value}}</td>
<td class="fixed-value"><button class="roll-button roll-resistanceBody-button"></button></td>
</tr>
</table>
</div>
</div>
<div class="flexcolumn-1">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/sundries/books/book-turquoise-moon.webp" class="flexpart-icon">{{localize "TYPES.Item.spell"}}</div>
<table>
<thead>
<tr>
<th>{{localize "ITEM.TypeSpell"}}</th>
<th>{{localize "midgard5.ew"}}</th>
<th></th>
<th></th>
<th class="title"><img src="/icons/svg/eye.svg" class="table-icon"></th>
<th class="title">{{localize "TYPES.Item.spell"}}</th>
<th class="title">{{localize "midgard5.spell-type"}}</th>
<th class="title">{{localize "midgard5.spell-castDuration-short"}}</th>
<th class="title">{{localize "midgard5.actor-ap-short"}}</th>
<th class="title">{{localize "midgard5.spell-range-short"}}</th>
<th class="title">{{localize "midgard5.spell-effectTarget"}}</th>
<th class="title">{{localize "midgard5.spell-effectArea-short"}}</th>
<th class="title">{{localize "midgard5.spell-effectDuration-short"}}</th>
<th class="title">{{localize "midgard5.ew"}}</th>
<th class="title"><img src="/systems/midgard5/assets/icons/icon/battle-gear.svg" class="table-icon"></th>
<th class="title"><img src="/icons/svg/d20.svg" class="table-icon"></th>
<td><a class="title add-spell"><i class="fa-regular fa-plus"></i></a></th>
</tr>
</thead>
<tbody>
<tbody class="items-list">
{{#each data.calc.spells as |item itemId|}}
<tr data-item="{{itemId}}">
<tr data-item-id="{{itemId}}" class="item">
<td class="flexpart-img"><img src={{item.icon}} class="flexpart-icon"></td>
<td class="padding edit-item">
<span>{{item.label}}</span>
<span class="spell-process">{{localize item.process}}</span>
</td>
<td class="fixed-value">{{localize (m5concat 'midgard5.spell-type-' item.type)}}</td>
<td class="fixed-value">{{item.castDuration}}</td>
<td class="fixed-value">{{item.ap}}</td>
<td class="fixed-value">{{item.range}}</td>
<td class="fixed-value">{{localize (m5concat 'midgard5.spell-target-' item.effectTarget)}}</td>
<td class="fixed-value">{{item.effectArea}}</td>
<td class="fixed-value">{{item.effectDuration}}</td>
<td class="fixed-value">{{item.calc.ew}}</td>
<td class="change-equipped">
{{#if item.equipped}}
<i class="fa-solid fa-circle-check"></i>
{{else}}
<i class="fa-regular fa-circle"></i>
{{/if}}
</td>
<td class="fixed-value"><button class="roll-button roll-weapon-button" /></td>
<td class="fixed-value"><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</div>
</div>
<div class="flexcolumn-1">
<div class="flexpart">
<div class="flexpart-header">{{localize "midgard5.pp"}} {{localize "midgard5.spells"}}</div>
<table>
<tbody>
<tr>
<td colspan="4">
<div class="flexrow">
{{#each data.lernKostenZauber as |group name|}}
{{#unless (eq group.kosten 0)}}
<span data-pp-name="{{name}}" class="pp-listing">
<label for="data.lernKostenZauber.{{name}}">{{localize (m5concat "midgard5.spell-process-" name)}}</label>
<span >
<i class="fa fa-minus-circle pp-decrease" style="cursor: pointer"></i>
<input style="width:15px" type="number" value={{group.pp}} data-dtype="Number" />
<i class="fa fa-plus-circle pp-increase" style="cursor: pointer"></i>
</span>
</span>
{{/unless}}
{{/each}}
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>

View File

@ -7,10 +7,84 @@
<table>
<tbody>
<tr>
<td>{{localize "midgard5.actor-lp"}}</td>
<td colspan="4">
<div class="flexrow">
<span>
<input id="data.equipped" type="checkbox" name="data.equipped" {{checked data.equipped}} />
<label for="data.equipped">{{localize "midgard5.equipped"}}</label>
</span>
<span>
<input id="data.magic" type="checkbox" name="data.magic" {{checked data.magic}} />
<label for="data.magic">{{localize "midgard5.magic"}}</label>
</span>
<span>
<input id="data.valuable" type="checkbox" name="data.valuable" {{checked data.valuable}}>
<label for="data.valuable">{{localize "midgard5.valuable"}}</label>
</span>
{{#if (eq item.parent.system.info.race "Zwerg")}}
<span>
<input id="data.hoarded" type="checkbox" name="data.hoarded" {{checked data.hoarded}}>
<label for="data.hoarded">{{localize "midgard5.hoarded"}}</label>
</span>
{{/if}}
</div>
</td>
</tr>
<tr>
<td colspan="4">
<div class="flexrow">
<span>{{localize "midgard5.item-value"}}</span>
<input name="data.value" type="number" value="{{data.value}}" data-dtype="Number" />
<select class="select-mod-operation" name="data.currency" data-type="String">
{{#select data.currency}}
<option value=""></option>
<option value="copper">{{localize "midgard5.currency-copper"}}</option>
<option value="silver">{{localize "midgard5.currency-silver"}}</option>
<option value="gold">{{localize "midgard5.currency-gold"}}</option>
{{/select}}
</select>
</div>
</td>
<td>
<div class="flexrow">
<span>{{localize "midgard5.item-weight"}}</span>
<input id="data.weight" type="number" name="data.weight" value="{{data.weight}}kg">
</div>
</td>
<td>
<div class="flexrow">
<span>{{localize "midgard5.item-abw"}}</span>
<input id="data.abw" type="number" name="data.abw" value="{{data.abw}}">
</div>
</td>
</tr>
<tr>
<td>
<div class="flexrow">
<span>{{localize "TYPES.Item.container"}}</span>
{{#if data.calc.containers}}
<select class="select-container" name="data.containerId" data-type="String">
{{#select data.containerId}}
<option value="">{{localize "midgard5.no-container"}}</option>
{{#each data.calc.containers as |container key|}}
<option value="{{key}}">{{container.label}}</option>
{{/each}}
{{/select}}
</select>
{{else}}
<span>{{localize "midgard5.assignItemToCharacter"}}</span>
{{/if}}
</div>
</td>
</tr>
<tr>
<td>{{localize "midgard5.lpProtection"}}</td>
<td><input name="data.lpProtection" type="text" value="{{data.lpProtection}}" data-dtype="Number" /></td>
<td>{{localize "midgard5.actor-ap"}}</td>
<td>{{localize "midgard5.apProtection"}}</td>
<td><input name="data.apProtection" type="text" value="{{data.apProtection}}" data-dtype="Number" /></td>
</tr>
@ -32,6 +106,9 @@
</tbody>
</table>
{{> "systems/midgard5/templates/sheets/partial/mod.hbs" mods=data.mods calc=data.calc}}
{{editor content=data.description target="data.description" button=true owner=owner editable=editable}}
</div>
</form>

View File

@ -0,0 +1,109 @@
<form class="" autocomplete="off">
<header class="sheet-header">
<img class="item-img" src="{{item.img}}" data-edit="img" title="{{item.name}}" />
<h1><input name="name" type="text" value="{{item.name}}" placeholder="Name" /></h1>
</header>
<nav class="sheet-navigation tabs" data-group="primary">
<a class="item active" data-tab="base_values">{{localize "midgard5.base_values"}}</a>
<a class="item" data-tab="skills">{{localize "midgard5.skills"}}</a>
<a class="item" data-tab="combat">{{localize "midgard5.combat"}}</a>
{{#if data.magicUsing}}
<a class="item" data-tab="spells">{{localize "midgard5.spells"}}</a>
{{/if}}
<a class="item" data-tab="description">{{localize "midgard5.description"}}</a>
</nav>
<section class="sheet-content">
<div class="tab base_values flexcol" data-group="primary" data-tab="base_values">
<table>
<tbody>
<tr>
<td colspan="4">
<div class="flexrow">
<span>
<input id="data.magicUsing" type="checkbox" name="data.magicUsing" {{checked data.magicUsing}} />
<label for="data.magicUsing">{{localize "midgard5.magicUsing"}}</label>
</span>
</div>
</td>
</tr>
<tr>
<td>{{localize "midgard5.resistanceMind"}}</td>
<td><input style="width:35px" name="data.resistanceMind" type="number" value="{{data.resistanceMind}}" data-dtype="Number" /></td>
<td>{{localize "midgard5.resistanceBody"}}</td>
<td><input style="width:35px" name="data.resistanceBody" type="number" value="{{data.resistanceBody}}" data-dtype="Number" /></td>
</tr>
</tbody>
</table>
</div>
<div class="tab skills flexcol" data-group="primary" data-tab="skills">
<table>
<tbody>
<tr>
<td colspan="4">
<div class="flexrow">
{{#each data.lernKostenAllgemein as |wert name|}}
<span style="flex: 1 0 26%">
<label for="data.lernKostenAllgemein.{{name}}">{{localize (m5concat "midgard5.skill-goup-" name)}}</label>
<input style="width:35px" name="data.lernKostenAllgemein.{{name}}" type="number" value={{wert}} data-dtype="Number" />
</span>
{{/each}}
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="tab combat flexcol" data-group="primary" data-tab="combat">
<table>
<tbody>
<tr>
<td colspan="4">
<div class="flexrow">
{{#each data.lernKostenKamptechnik as |wert name|}}
<span style="flex: 1 0 26%">
<label for="data.lernKostenKamptechnik.{{name}}">{{localize (m5concat "midgard5." name)}}</label>
<input style="width:35px" name="data.lernKostenKamptechnik.{{name}}" type="number" value={{wert}} data-dtype="Number" />
</span>
{{/each}}
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="tab spells flexcol" data-group="primary" data-tab="spells">
<table>
<tbody>
<tr>
<td colspan="4">
<div class="flexrow">
{{#each data.lernKostenZauber as |wert name|}}
<span style="flex: 1 0 26%">
<label for="data.lernKostenZauber.{{name}}">{{localize (m5concat "midgard5.spell-process-" name)}}</label>
<input style="width:35px" name="data.lernKostenZauber.{{name}}.kosten" type="number" value={{wert.kosten}} data-dtype="Number" />
</span>
{{/each}}
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="tab description flexcol" data-group="primary" data-tab="description">
{{editor content=data.description target="data.description" button=true owner=owner editable=editable}}
</div>
</section>
</form>

View File

@ -0,0 +1,73 @@
<form class="item-sheet {{cssClass}} m5item-item" autocomplete="off">
<header class="sheet-header">
<img class="item-img" src="{{item.img}}" data-edit="img" title="{{item.name}}" />
<h1><input name="name" type="text" value="{{item.name}}" placeholder="Name" /></h1>
</header>
<div class="sheet-content">
<table>
<tr>
<td colspan=4>
<div class="flexrow">
<span>
<input id="data.equipped" type="checkbox" name="data.equipped" {{checked data.equipped}}>
<label for="data.equipped">{{localize "midgard5.equipped"}}</label>
</span>
<span>
<input id="data.magic" type="checkbox" name="data.magic" {{checked data.magic}}>
<label for="data.magic">{{localize "midgard5.magic"}}</label>
</span>
</div>
</td>
<td>
<div class="flexrow">
<span>{{localize "midgard5.item-abw"}}</span>
<input id="data.abw" type="number" name="data.abw" value="{{data.abw}}">
</div>
</td>
</tr>
<tr>
<td>
<div class="flexrow">
<span>{{localize "midgard5.item-quantity"}}</span>
<input id="data.quantity" type="number" name="data.quantity" value="{{data.quantity}}">
</div>
</td>
<td>
<div class="flexrow">
<span>{{localize "midgard5.capacity"}}</span>
<input id="data.capacity" type="number" name="data.capacity" value="{{data.capacity}}">
</div>
</td>
</tr>
<tr>
<td>
<div class="flexrow">
<span>{{localize "midgard5.item-value"}}</span>
<input name="data.value" type="number" value="{{data.value}}" data-dtype="Number" />
<select class="select-mod-operation" name="data.currency" data-type="String">
{{#select data.currency}}
<option value=""></option>
<option value="copper">{{localize "midgard5.currency-copper"}}</option>
<option value="silver">{{localize "midgard5.currency-silver"}}</option>
<option value="gold">{{localize "midgard5.currency-gold"}}</option>
{{/select}}
</select>
</div>
</td>
<td>
<div class="flexrow">
<span>{{localize "midgard5.item-weight"}}</span>
<input id="data.weight" type="number" name="data.weight" value="{{data.weight}}">
</div>
</td>
</tr>
</table>
{{> "systems/midgard5/templates/sheets/item/rolls.hbs"}}
{{> "systems/midgard5/templates/sheets/partial/mod.hbs" mods=data.mods calc=data.calc}}
{{editor content=data.description target="data.description" button=true owner=owner editable=editable}}
</div>
</form>

View File

@ -7,8 +7,12 @@
<table>
<tbody>
<tr>
<td colspan=4>
<td colspan="4">
<div class="flexrow">
<span>
<input id="data.equipped" type="checkbox" name="data.equipped" {{checked data.equipped}}>
<label for="data.equipped">{{localize "midgard5.equipped"}}</label>
</span>
<span>
<input id="data.magic" type="checkbox" name="data.magic" {{checked data.magic}}>
<label for="data.magic">{{localize "midgard5.magic"}}</label>
@ -18,6 +22,65 @@
<input id="data.special" type="checkbox" name="data.special" {{checked data.special}}>
<label for="data.special">{{localize "midgard5.special"}}</label>
</span>
<span>
<input id="data.valuable" type="checkbox" name="data.valuable" {{checked data.valuable}}>
<label for="data.valuable">{{localize "midgard5.valuable"}}</label>
</span>
{{#if (eq item.parent.system.info.race "Zwerg")}}
<span>
<input id="data.hoarded" type="checkbox" name="data.hoarded" {{checked data.hoarded}}>
<label for="data.hoarded">{{localize "midgard5.hoarded"}}</label>
</span>
{{/if}}
</div>
</td>
</tr>
<tr>
<td colspan="4">
<div class="flexrow">
<span>{{localize "midgard5.item-value"}}</span>
<input name="data.value" type="number" value="{{data.value}}" data-dtype="Number" />
<select class="select-mod-operation" name="data.currency" data-type="String">
{{#select data.currency}}
<option value=""></option>
<option value="copper">{{localize "midgard5.currency-copper"}}</option>
<option value="silver">{{localize "midgard5.currency-silver"}}</option>
<option value="gold">{{localize "midgard5.currency-gold"}}</option>
{{/select}}
</select>
</div>
</td>
<td>
<div class="flexrow">
<span>{{localize "midgard5.item-weight"}}</span>
<input id="data.weight" type="number" name="data.weight" value="{{data.weight}}kg">
</div>
</td>
<td>
<div class="flexrow">
<span>{{localize "midgard5.item-abw"}}</span>
<input id="data.abw" type="number" name="data.abw" value="{{data.abw}}">
</div>
</td>
</tr>
<tr>
<td>
<div class="flexrow">
<span>{{localize "TYPES.Item.container"}}</span>
{{#if data.calc.containers}}
<select class="select-container" name="data.containerId" data-type="String">
{{#select data.containerId}}
<option value="">{{localize "midgard5.no-container"}}</option>
{{#each data.calc.containers as |container key|}}
<option value="{{key}}">{{container.label}}</option>
{{/each}}
{{/select}}
</select>
{{else}}
<span>{{localize "midgard5.assignItemToCharacter"}}</span>
{{/if}}
</div>
</td>
</tr>

View File

@ -0,0 +1,46 @@
<form class="item-sheet {{cssClass}} m5item-item" autocomplete="off">
<header class="sheet-header">
<img class="item-img" src="{{item.img}}" data-edit="img" title="{{item.name}}" />
<h1><input name="name" type="text" value="{{item.name}}" placeholder="Name" /></h1>
</header>
<div class="sheet-content">
<table>
<tr>
<td colspan=4>
<div class="flexrow">
<span>
<input id="data.equipped" type="checkbox" name="data.equipped" {{checked data.equipped}}>
<label for="data.equipped">{{localize "midgard5.active"}}</label>
</span>
<span>
<input id="data.magic" type="checkbox" name="data.magic" {{checked data.magic}}>
<label for="data.magic">{{localize "midgard5.magic"}}</label>
</span>
</div>
</td>
</tr>
<tr>
<td>
<div class="flexrow">
<span>{{localize "midgard5.time-duration"}}</span>
<input name="data.duration.time" type="text" value="{{data.duration.time}}" data-dtype="Number" />
<select class="select-mod-operation" name="data.duration.unit" data-type="String">
{{#select data.duration.unit}}
<option value=""></option>
<option value="round">{{localize "midgard5.time-round"}}</option>
<option value="minute">{{localize "midgard5.time-minute"}}</option>
<option value="hour">{{localize "midgard5.time-hour"}}</option>
<option value="limitless">{{localize "midgard5.time-limitless"}}</option>
{{/select}}
</select>
</div>
</td>
</tr>
</table>
{{> "systems/midgard5/templates/sheets/partial/mod.hbs" mods=data.mods calc=data.calc}}
{{editor content=data.description target="data.description" button=true owner=owner editable=editable}}
</div>
</form>

View File

@ -6,72 +6,90 @@
<div class="sheet-content">
<table>
<tr>
<td>
<td colspan="4">
<div class="flexrow">
<span>
<input id="data.equipped" type="checkbox" name="data.equipped" {{checked data.equipped}}>
<label for="data.equipped">{{localize "midgard5.equipped"}}</label>
</span>
<span>
<input id="data.magic" type="checkbox" name="data.magic" {{checked data.magic}}>
<label for="data.magic">{{localize "midgard5.magic"}}</label>
</span>
<span>
<input id="data.valuable" type="checkbox" name="data.valuable" {{checked data.valuable}}>
<label for="data.valuable">{{localize "midgard5.valuable"}}</label>
</span>
{{#if (eq item.parent.system.info.race "Zwerg")}}
<span>
<input id="data.hoarded" type="checkbox" name="data.hoarded" {{checked data.hoarded}}>
<label for="data.hoarded">{{localize "midgard5.hoarded"}}</label>
</span>
{{/if}}
</div>
</td>
</tr>
<tr>
<td>
<div class="flexrow">
<span>{{localize "midgard5.item-quantity"}}</span>
<input id="data.quantity" type="number" name="data.quantity" value="{{data.quantity}}">
</div>
</td>
<td colspan="4">
<div class="flexrow">
<span>{{localize "midgard5.item-value"}}</span>
<input name="data.value" type="number" value="{{data.value}}" data-dtype="Number" />
<select class="select-mod-operation" name="data.currency" data-type="String">
{{#select data.currency}}
<option value=""></option>
<option value="copper">{{localize "midgard5.currency-copper"}}</option>
<option value="silver">{{localize "midgard5.currency-silver"}}</option>
<option value="gold">{{localize "midgard5.currency-gold"}}</option>
{{/select}}
</select>
</div>
</td>
<td>
<div class="flexrow">
<span>{{localize "midgard5.item-value"}}</span>
<input name="data.value" type="text" value="{{data.value}}" data-dtype="Number" />
<span>{{localize "midgard5.item-weight"}}</span>
<input id="data.weight" type="number" name="data.weight" value="{{data.weight}}">
</div>
</td>
<td>
<div class="flexrow">
<span>{{localize "midgard5.item-abw"}}</span>
<input id="data.abw" type="number" name="data.abw" value="{{data.abw}}">
</div>
</td>
</tr>
<tr>
<td>
<div class="flexrow">
<span>{{localize "TYPES.Item.container"}}</span>
{{#if data.calc.containers}}
<select class="select-container" name="data.containerId" data-type="String">
{{#select data.containerId}}
<option value="">{{localize "midgard5.no-container"}}</option>
{{#each data.calc.containers as |container key|}}
<option value="{{key}}">{{container.label}}</option>
{{/each}}
{{/select}}
</select>
{{else}}
<span>{{localize "midgard5.assignItemToCharacter"}}</span>
{{/if}}
</div>
</td>
</tr>
</table>
<table>
<thead>
<tr>
<th>Mods</th>
<th></th>
<th></th>
<th><button class="add-mod">+</button></th>
</tr>
</thead>
<tbody>
{{#each data.mods as |mod modId|}}
<tr>
<td>
<select class="select-mod-type" name="data.mods.{{modId}}.type" data-type="String">
{{#select mod.type}}
<option value="attribute">{{localize "midgard5.attribute"}}</option>
<option value="stat">{{localize "midgard5.bonus"}}</option>
<option value="skill">{{localize "midgard5.skill"}}</option>
{{/select}}
</select>
</td>
{{> "systems/midgard5/templates/sheets/item/rolls.hbs"}}
<td>
<select class="select-id" name="data.mods.{{modId}}.id" data-type="String">
{{#select mod.id}}
<option value="">{{localize "midgard5.no-skill"}}</option>
{{#each (lookup ../data.calc.mods modId) as |name key|}}
<option value="{{key}}">{{name}}</option>
{{/each}}
{{/select}}
</select>
</td>
{{> "systems/midgard5/templates/sheets/partial/mod.hbs" mods=data.mods calc=data.calc}}
<td>
<select class="select-mod-operation" name="data.mods.{{modId}}.operation" data-type="String">
{{#select mod.operation}}
{{#if (eq mod.type "attribute")}}
<option value="add100">{{localize "midgard5.mod-operation-add100"}}</option>
{{/if}}
<option value="add">{{localize "midgard5.mod-operation-add"}}</option>
<option value="set">{{localize "midgard5.mod-operation-set"}}</option>
<option value="fixed">{{localize "midgard5.mod-operation-fixed"}}</option>
{{/select}}
</select>
</td>
<td>
<input name="data.mods.{{modId}}.value" type="text" value="{{mod.value}}" data-dtype="Number" />
</td>
</tr>
{{/each}}
</tbody>
</table>
{{editor content=data.description target="data.description" button=true owner=owner editable=editable}}
</div>

View File

@ -0,0 +1,125 @@
<form class="item-sheet {{cssClass}}" autocomplete="off">
<header class="sheet-header">
<img class="item-img" src="{{item.img}}" data-edit="img" title="{{item.name}}" />
<h1><input name="name" type="text" value="{{item.name}}" placeholder="Name" /></h1>
</header>
<div class="sheet-content">
<table>
<tbody>
<tr>
<td colspan=4>
<div class="flexrow">
<span>
<input id="data.isKido" type="checkbox" name="data.isKido" {{checked data.isKido}}>
<label for="data.isKido">{{localize "midgard5.kido"}}</label>
</span>
</div>
</td>
</tr>
<tr>
<td>{{localize "midgard5.bonus"}}</td>
<td><input name="data.bonus" type="text" value="{{data.bonus}}" data-dtype="Number" /></td>
<td>{{localize "midgard5.actor-ap"}}</td>
<td><input name="data.ap" type="text" value="{{data.ap}}" data-dtype="String" /></td>
</tr>
<tr>
<td>{{localize "midgard5.kampfkunst-ep"}}</td>
<td><input name="data.ep" type="text" value="{{data.ep}}" data-dtype="String" /></td>
{{#unless item.system.isKido}}
<td>{{localize "midgard5.kampfkunst-rank"}}</td>
<td><input name="data.rank" type="number" value="{{data.rank}}" data-dtype="Number" /></td>
{{/unless}}
</tr>
<tr>
<td>{{localize "midgard5.kampfkunst-weapon"}}</td>
<td><input name="data.weapon" type="text" value="{{data.weapon}}" data-dtype="String" /></td>
<td>{{localize "midgard5.kampfkunst-enemy"}}</td>
<td><input name="data.enemy" type="text" value="{{data.enemy}}" data-dtype="String" /></td>
</tr>
<tr>
{{#unless item.system.isKido}}
<td>{{localize "midgard5.kampfkunst-type"}}</td>
<td>
<select class="select-type" name="data.type" data-type="String">
{{#select data.type}}
{{#each data.kampfkunstTypeSelection as |label key|}}
<option value="{{key}}">{{localize label}}</option>
{{/each}}
{{/select}}
</select>
</td>
{{else}}
<td>{{localize "midgard5.kido-type"}}</td>
<td>
<select class="select-type" name="data.type" data-type="String">
{{#select data.type}}
{{#each data.kidoTypeSelection as |label key|}}
<option value="{{key}}">{{localize label}}</option>
{{/each}}
{{/select}}
</select>
</td>
{{/unless}}
{{#unless item.system.isKido}}
<td>{{localize "midgard5.kampfkunst-variante"}}</td>
<td>
<select class="select-variante" name="data.variante" data-type="String">
{{#select data.variante}}
{{#each data.kampfkunstVarianteSelection as |label key|}}
<option value="{{key}}">{{localize label}}</option>
{{/each}}
{{/select}}
</select>
</td>
{{else}}
{{#unless (eq item.system.type "finte")}}
<td>{{localize "midgard5.kido-variante"}}</td>
<td>
<select class="select-variante" name="data.variante" data-type="String">
{{#select data.variante}}
{{#each data.kidoVarianteSelection as |label key|}}
<option value="{{key}}">{{localize label}}</option>
{{/each}}
{{/select}}
</select>
</td>
{{/unless}}
{{/unless}}
{{#if item.system.isKido}}
<tr>
<td>{{localize "midgard5.kido-color"}}</td>
<td><input name="data.color" type="text" value="{{data.color}}" data-dtype="String" /></td>
<td>{{localize "midgard5.kido-style"}}</td>
<td><input name="data.style" type="text" value="{{data.style}}" data-dtype="String" /></td>
</tr>
<tr>
<td>{{localize "midgard5.kido-grade"}}</td>
<td><input name="data.grade" type="text" value="{{data.grade}}" data-dtype="String" /></td>
<td>{{localize "midgard5.kido-rank"}}</td>
<td><input name="data.rank" type="number" value="{{data.rank}}" data-dtype="Number" /></td>
</tr>
{{/if}}
</tr>
<td>{{localize "midgard5.skill"}}</td>
<td>
{{#if data.calc.generalSkills}}
<select class="select-skill" name="data.skillId" data-type="String">
{{#select data.skillId}}
<option value="">{{localize "midgard5.no-skill"}}</option>
{{#each data.calc.generalSkills as |skill key|}}
<option value="{{key}}">{{skill.label}}</option>
{{/each}}
{{/select}}
</select>
{{else}}
<span>{{localize "midgard5.assignItemToCharacter"}}</span>
{{/if}}
</td>
</tbody>
</table>
{{> "systems/midgard5/templates/sheets/item/rolls.hbs"}}
{{editor content=data.description target="data.description" button=true owner=owner editable=editable}}
</div>
</form>

View File

@ -9,8 +9,14 @@
<tr>
<td>{{localize "midgard5.bonus"}}</td>
<td><input name="data.bonus" type="text" value="{{data.bonus}}" data-dtype="Number" /></td>
<td>{{localize "midgard5.spell-material"}}</td>
<td><input name="data.material" type="text" value="{{data.material}}" data-dtype="String" /></td>
</tr>
<tr>
<td>{{localize "midgard5.actor-ap"}}</td>
<td><input name="data.ap" type="text" value="{{data.ap}}" data-dtype="String" /></td>
<td>{{localize "midgard5.actor-lp"}}</td>
<td><input name="data.lp" type="text" value="{{data.lp}}" data-dtype="String" /></td>
</tr>
<tr>
<td>{{localize "midgard5.spell-castDuration"}}</td>
@ -60,6 +66,12 @@
</select>
</td>
</tr>
<tr>
<td>{{localize "midgard5.spell-agens"}}</td>
<td><input name="data.agens" type="text" value="{{data.agens}}" data-dtype="String" /></td>
<td>{{localize "midgard5.spell-reagens"}}</td>
<td><input name="data.reagens" type="text" value="{{data.reagens}}" data-dtype="String" /></td>
</tr>
</tbody>
</table>

View File

@ -7,8 +7,12 @@
<table>
<tbody>
<tr>
<td colspan=4>
<td colspan="5">
<div class="flexrow">
<span>
<input id="data.equipped" type="checkbox" name="data.equipped" {{checked data.equipped}}>
<label for="data.equipped">{{localize "midgard5.equipped"}}</label>
</span>
<span>
<input id="data.magic" type="checkbox" name="data.magic" {{checked data.magic}}>
<label for="data.magic">{{localize "midgard5.magic"}}</label>
@ -23,6 +27,65 @@
<input id="data.special" type="checkbox" name="data.special" {{checked data.special}}>
<label for="data.special">{{localize "midgard5.special"}}</label>
</span>
<span>
<input id="data.valuable" type="checkbox" name="data.valuable" {{checked data.valuable}}>
<label for="data.valuable">{{localize "midgard5.valuable"}}</label>
</span>
{{#if (eq item.parent.system.info.race "Zwerg")}}
<span>
<input id="data.hoarded" type="checkbox" name="data.hoarded" {{checked data.hoarded}}>
<label for="data.hoarded">{{localize "midgard5.hoarded"}}</label>
</span>
{{/if}}
</div>
</td>
</tr>
<tr>
<td colspan="4">
<div class="flexrow">
<span>{{localize "midgard5.item-value"}}</span>
<input name="data.value" type="number" value="{{data.value}}" data-dtype="Number" />
<select class="select-mod-operation" name="data.currency" data-type="String">
{{#select data.currency}}
<option value=""></option>
<option value="copper">{{localize "midgard5.currency-copper"}}</option>
<option value="silver">{{localize "midgard5.currency-silver"}}</option>
<option value="gold">{{localize "midgard5.currency-gold"}}</option>
{{/select}}
</select>
</div>
</td>
<td>
<div class="flexrow">
<span>{{localize "midgard5.item-weight"}}</span>
<input id="data.weight" type="number" name="data.weight" value="{{data.weight}}kg">
</div>
</td>
<td>
<div class="flexrow">
<span>{{localize "midgard5.item-abw"}}</span>
<input id="data.abw" type="number" name="data.abw" value="{{data.abw}}">
</div>
</td>
</tr>
<tr>
<td>
<div class="flexrow">
<span>{{localize "TYPES.Item.container"}}</span>
{{#if data.calc.containers}}
<select class="select-container" name="data.containerId" data-type="String">
{{#select data.containerId}}
<option value="">{{localize "midgard5.no-container"}}</option>
{{#each data.calc.containers as |container key|}}
<option value="{{key}}">{{container.label}}</option>
{{/each}}
{{/select}}
</select>
{{else}}
<span>{{localize "midgard5.assignItemToCharacter"}}</span>
{{/if}}
</div>
</td>
</tr>

View File

@ -0,0 +1,4 @@
<div class="sheet-npc" style="flex: 1 0 20%" data-attribute="{{attributeId}}">
<div class="attribute-header">{{localize (m5concat "midgard5.actor-" attributeId "-long")}}</div>
<div class="attribute-value"> <input class="attribute-footer-value" name="data.attributes.{{attributeId}}.value" value="{{attribute.value}}" type="text" data-dtype="Number" /></div>
</div>

View File

@ -0,0 +1,233 @@
<div class="flexbox">
<div class="flexcolumn-3">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/magic/time/arrows-circling-pink.webp" class="flexpart-icon">{{localize "midgard5.calculated-values"}}</div>
<table>
<tr height = 10px></tr>
<tr>
<td>{{localize "midgard5.movementRange"}}</td>
<td class="fixed-value">{{data.calc.stats.movement.value}}</td>
<td></td>
<td class="fixed-value"></td>
</tr>
<tr>
<td>{{localize "midgard5.initiative"}}</td>
<td class="fixed-value">
{{#if (isSkillInList (localizeMidgard "anfuehren") data.calc.skills.general)}}
{{skillEwInList (localizeMidgard "anfuehren") data.calc.skills.general}}
{{else}}
{{skillEw actor._id data.skills.general.anfuehren}}
{{/if}}
</td>
<td>{{localize "midgard5.actionrank"}}</td>
<td class="fixed-value"><a class="join-combat">{{data.calc.attributes.gw.value}}</a></td>
</tr>
</table>
</div>
</div>
<div class="flexcolumn-3">
<div class="flexpart" style="padding: 0 0.5rem;">
<div class="flexpart-header">{{localize "midgard5.actionrank"}}</div>
<button class="wide-button join-combat">{{localize "midgard5.combat-join"}}</button>
<button class="wide-button ranged-combat">{{localize "midgard5.combat-ranged"}}</button>
<button class="wide-button spell-combat">{{localize "midgard5.combat-spell"}}</button>
</div>
</div>
<div class="flexcolumn-3">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/magic/life/cross-worn-green.webp" class="flexpart-icon">{{localize "TYPES.Item.effect"}}</div>
<table>
<thead>
<tr>
<th class="title"><img src="/icons/svg/eye.svg" class="table-icon"></th>
<th class="title">{{localize "TYPES.Item.effect"}}</th>
<td><a class="title add-effect"><i class="fa-regular fa-plus"></i></a></th>
</tr>
</thead>
<tbody class="items-list">
{{#each data.calc.gear.effects as |item itemId|}}
<tr data-item-id="{{itemId}}" class="items">
<td class="flexpart-img"><img src={{item.icon}} class="flexpart-icon"></td>
<td class="padding">
<span class="edit-item">{{item.label}}</span>
{{#if item.equipped}}
<span class="spell-process">{{localize "midgard5.active"}}</span>
{{#unless (or (eq item.duration.unit "") (eq item.duration.unit "limitless"))}}
<span class="spell-process">{{item.duration.time}} {{localize (concat "midgard5.time-" item.duration.unit)}}</span>
{{/unless}}
{{/if}}
</td>
{{!--{{#unless (eq item.label "Belastung")}}--}}
<td class="fixed-value"><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
{{!--{{/unless}}--}}
</tr>
{{/each}}
</tbody>
</table>
</div>
</div>
<div class="flexcolumn-3">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/skills/melee/hand-grip-sword-white-brown.webp" class="flexpart-icon">{{localize "midgard5.attack"}}</div>
<table>
<thead>
<tr>
<th class="title"><img src="/icons/svg/eye.svg" class="table-icon"></th>
<th class="title">{{localize "TYPES.Item.weapon"}}</th>
<th class="title">{{localize "midgard5.ew"}}</th>
<th class="title">{{localize "midgard5.damage"}}</th>
<th class="title"><img src="/icons/svg/d20.svg" class="table-icon"></th>
<td><a class="title add-weapon"><i class="fa-regular fa-plus"></i></a></th>
</tr>
</thead>
<tbody class="items-list">
{{#each data.calc.gear.weapons as |item itemId|}}
<tr data-item-id="{{itemId}}" class="item">
<td class="flexpart-img"><img src={{item.icon}} class="flexpart-icon"></td>
<td class="padding edit-item {{#if item.special}}highlight{{/if}}">{{item.label}}{{#if item.special}}(*){{/if}}</td>
<td class="fixed-value">{{item.calc.ew}}</td>
<td class="fixed-value">{{item.damageBase}}</td>
<td><button class="roll-button roll-weapon-button"></button></td>
<td><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/each}}
</tbody>
</table>
<table>
<thead>
<tr>
<th class="title"><img src="/icons/svg/eye.svg" class="table-icon"></th>
<th class="title">{{localize "midgard5.weapon-skill"}}</th>
<th class="title">{{localize "midgard5.ew"}}</th>
<th class="title"><img src="/icons/svg/d20.svg" class="table-icon"></th>
<th><a class="title add-combat-skill"><i class="fa-regular fa-plus"></i></th>
</tr>
</thead>
<tbody class="items-list">
{{#each data.calc.skills.combat as |skill skillId|}}
<tr data-item-id="{{skillId}}" class="item">
<td class="flexpart-img"><img src={{skill.icon}} class="flexpart-icon"></td>
<td class="padding edit-item">{{skill.label}}</td>
<td class="fixed-value">{{skill.calc.ew}}</td>
<td><button class="roll-button roll-learned-button"></button></td>
<td><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</div>
<div class="flexcolumn-3">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/skills/melee/shield-block-gray-orange.webp" class="flexpart-icon">{{localize "midgard5.defense"}}</div>
<table>
<tr height = 10px></tr>
<tr>
<td class="padding highlight">{{localize "midgard5.defense"}}</td>
<td class="center">{{add data.calc.stats.defense.value data.calc.stats.defenseBonus.value}}</td>
<td class="fixed-value"><button class="roll-button roll-defense-button"></button></td>
</tr>
<tr>
<td class="padding highlight">{{localize "midgard5.resistanceMind"}}</td>
<td class="center">{{data.calc.stats.resistanceMind.value}}</td>
<td class="fixed-value"><button class="roll-button roll-resistanceMind-button"></button></td>
</tr>
<tr>
<td class="padding highlight">{{localize "midgard5.resistanceBody"}}</td>
<td class="center">{{data.calc.stats.resistanceBody.value}}</td>
<td class="fixed-value"><button class="roll-button roll-resistanceBody-button"></button></td>
</tr>
</table>
<table>
<thead>
<tr>
<th class="title"><img src="/icons/svg/eye.svg" class="table-icon"></th>
<th class="title">{{localize "TYPES.Item.defensiveWeapon"}}</th>
<th class="title">{{localize "midgard5.ew"}}</th>
<th class="title"><img src="/icons/svg/d20.svg" class="table-icon"></th>
<th><a class="title add-defensiveWeapon"><i class="fa-regular fa-plus"></i></a></th>
</tr>
</thead>
<tbody class="items-list">
{{#each data.calc.gear.defensiveWeapons as |item itemId|}}
<tr data-item-id="{{itemId}}" class="item">
<td class="flexpart-img"><img src={{item.icon}} class="flexpart-icon"></td>
<td class="padding edit-item">{{item.label}}</td>
<td class="fixed-value">{{item.calc.ew}}</td>
<td><button class="roll-button roll-weapon-button"></button></td>
<td><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/each}}
</tbody>
</table>
<table>
<thead>
<tr>
<th class="title"><img src="/icons/svg/eye.svg" class="table-icon"></th>
<th class="title">{{localize "TYPES.Item.armor"}}</th>
<th class="title">{{localize "midgard5.actor-lp-short"}}</th>
<th><a class="title add-armor"><i class="fa-regular fa-plus"></i></a></th>
</tr>
</thead>
<tbody class="items-list">
{{#each data.calc.gear.armor as |item itemId|}}
<tr data-item-id="{{itemId}}" class="item">
<td class="flexpart-img"><img src={{item.icon}} class="flexpart-icon"></td>
<td class="padding edit-item">{{item.label}}</td>
<td class="fixed-value">{{lpProtection}}</td>
<td><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</div>
{{#if actor.system.info.magicUsing }}
<div class="flexcolumn-3">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/magic/symbols/star-inverted-yellow.webp" class="flexpart-icon">{{localize "TYPES.Item.spell"}}</div>
<table>
<tr height = 10px></tr>
<tr>
<td class="padding highlight">{{localize "midgard5.spellCasting"}}</td>
<td class="center">{{data.calc.stats.spellCasting.value}}</td>
<td class="fixed-value"><button class="roll-button roll-defense-button"></button></td>
</tr>
</table>
<table>
<thead>
<tr>
<th class="title"><img src="/icons/svg/eye.svg" class="table-icon"></th>
<th class="title">{{localize "TYPES.Item.spell"}}</th>
<th class="title">{{localize "midgard5.ew"}}</th>
<th class="title"><img src="/icons/svg/d20.svg" class="table-icon"></th>
<th><a class="title add-spell"><i class="fa-regular fa-plus"></i></a></th>
</tr>
</thead>
<tbody class="items-list">
{{#each data.calc.spells as |item itemId|}}
<tr data-item-id="{{itemId}}" class="item">
<td class="flexpart-img"><img src={{item.icon}} class="flexpart-icon"></td>
<td class="padding edit-item {{#if item.special}}highlight{{/if}}">{{item.label}}{{#if item.special}}(*){{/if}}</td>
<td class="fixed-value">{{item.calc.ew}}</td>
<td><button class="roll-button roll-weapon-button"></button></td>
<td><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</div>
{{/if}}
</div>

View File

@ -0,0 +1,18 @@
<div class="flexbox">
<div class="flexcolumn-1">
<div class="flexpart" style="height: 250px;">
<div class="flexpart-header"><img src="icons/environment/wilderness/mine-interior-dungeon-door.webp" class="flexpart-icon" />{{localize "midgard5.description"}}</div>
<br />
<div class="biography">{{editor data.info.description target="data.info.description" button=true owner=owner editable=editable}}</div>
</div>
</div>
<div class="flexcolumn-1">
<div class="flexpart" style="height: 250px;">
<div class="flexpart-header"><img src="icons/environment/people/group.webp" class="flexpart-icon" />{{localize "midgard5.background"}}</div>
<br />
<div class="biography">{{editor data.info.background target="data.info.background" button=true owner=owner editable=editable}}</div>
</div>
</div>
</div>

View File

@ -0,0 +1,127 @@
<form class="actor-sheet {{cssClass}}" autocomplete="off">
<header class="flexbox" style="background-color: beige; padding: 5px; border: 2px solid black;">
<!-- Logo -->
<div class="flexcolumn-5" style="height: 200px;">
<img class="profile-img" src="/systems/midgard5/assets/icons/backgrounds/bg1.webp" alt="Midgard">
</div>
<!-- Name, Class, Level, Race, Occupation -->
<div class="flexcolumn-2" style="margin:0px 5px 0px 5px;">
<table class="bordered">
<tr>
<td >{{localize "midgard5.actor-name"}}</td>
<td colspan="3"><input name="name" type="text" value="{{actor.name}}" data-dtype="String" /></td>
</tr>
<tr>
<td >{{localize "midgard5.class"}}</td>
<td ><input name="data.info.npc-class" type="text" value="{{data.info.npc-class}}" data-dtype="String" /></td>
<td >{{localize "midgard5.level"}}</td>
<td>{{data.calc.level}}</td>
</table>
<table style="font-weight: bold;">
<tr height = 10px></tr>
<tr>
<td ><input name="data.info.race" type="text" value="{{data.info.race}}" data-dtype="String" /></td>
<td ><input name="data.info.occupation" type="text" value="{{data.info.occupation}}" data-dtype="String" /></td>
</tr>
<tr>
<td style="text-align: center; font-size: small">{{localize "midgard5.race"}}</td>
<td style="text-align: center; font-size: small">{{localize "midgard5.occupation"}}</td>
</tr>
</table>
<table style="width: 100%;">
<tr>
<td class="attribute-value roll-attribute-button" data-attribute="st" data-value="{{data.calc.attributes.st.value}}">{{data.calc.attributes.st.value}}</td>
<td class="attribute-value roll-attribute-button" data-attribute="gs" data-value="{{data.calc.attributes.gs.value}}">{{data.calc.attributes.gs.value}}</td>
<td class="attribute-value roll-attribute-button" data-attribute="gw" data-value="{{data.calc.attributes.gw.value}}">{{data.calc.attributes.gw.value}}</td>
<td class="attribute-value roll-attribute-button" data-attribute="ko" data-value="{{data.calc.attributes.ko.value}}">{{data.calc.attributes.ko.value}}</td>
<td class="attribute-value roll-attribute-button" data-attribute="in" data-value="{{data.calc.attributes.in.value}}">{{data.calc.attributes.in.value}}</td>
<td class="attribute-value roll-attribute-button" data-attribute="zt" data-value="{{data.calc.attributes.zt.value}}">{{data.calc.attributes.zt.value}}</td>
<td class="attribute-value roll-attribute-button" data-attribute="au" data-value="{{data.calc.attributes.au.value}}">{{data.calc.attributes.au.value}}</td>
<td class="attribute-value roll-attribute-button" data-attribute="pa" data-value="{{data.calc.attributes.pa.value}}">{{data.calc.attributes.pa.value}}</td>
<td class="attribute-value roll-attribute-button" data-attribute="wk" data-value="{{data.calc.attributes.wk.value}}">{{data.calc.attributes.wk.value}}</td>
<td class="attribute-value roll-attribute-button" data-attribute="git" data-value="{{data.calc.stats.poisonResistance.value}}">{{data.calc.stats.poisonResistance.value}}</td>
</tr>
<tr>
<td class="attribute">{{localize "midgard5.actor-st"}}</td>
<td class="attribute">{{localize "midgard5.actor-gs"}}</td>
<td class="attribute">{{localize "midgard5.actor-gw"}}</td>
<td class="attribute">{{localize "midgard5.actor-ko"}}</td>
<td class="attribute">{{localize "midgard5.actor-in"}}</td>
<td class="attribute">{{localize "midgard5.actor-zt"}}</td>
<td class="attribute">{{localize "midgard5.actor-au"}}</td>
<td class="attribute">{{localize "midgard5.actor-pa"}}</td>
<td class="attribute">{{localize "midgard5.actor-wk"}}</td>
<td class="attribute">{{localize "midgard5.actor-git"}}</td>
</tr>
</table>
</div>
<!-- Profilbild -->
<div class="flexcolumn-5" style="height: 200px;text-align: center;" >
<img class="profile-img" src="{{actor.img}}" data-edit="img" title="{{actor.name}}" />
</div>
<!-- LP + AP -->
<div class="flexcolumn-1">
<table>
<tr>
<td><b>{{localize "midgard5.actor-lp-short"}}</b></td>
<td colspan="9">
<div class="health-bar">
<input name="data.lp.value" type="text" value="{{data.lp.value}}" data-dtype="Number" />
{{#times data.lp.max}}
{{#if (lt this ../data.lp.value)}}
<div class="lp-bar-item update-lp" data-value="{{this}}"></div>
{{else}}
<div class="lp-bar-item-empty update-lp" data-value="{{this}}"></div>
{{/if}}
{{/times}}
<div class="max-value">{{data.lp.max}}</div>
</div>
</td>
</tr>
<tr>
<td><b>{{localize "midgard5.actor-ap-short"}}</b></td>
<td colspan="9">
<div class="health-bar">
<input name="data.ap.value" type="text" value="{{data.ap.value}}" data-dtype="Number" />
{{#times data.ap.max}}
{{#if (lt this ../data.ap.value)}}
<div class="ap-bar-item update-ap" data-value="{{this}}"></div>
{{else}}
<div class="ap-bar-item-empty update-ap" data-value="{{this}}"></div>
{{/if}}
{{/times}}
<div class="max-value">{{data.ap.max}}</div>
</div>
</td>
</tr>
</table>
</div>
</header>
{{!-- Character Sheet Navigation --}}
<nav class="sheet-navigation tabs" data-group="primary">
<a class="item active" data-tab="combat">{{ localize "midgard5.combat" }}</a>
<a class="item" data-tab="properties">{{ localize "midgard5.attributes" }}</a>
<a class="item" data-tab="description">{{ localize "midgard5.description" }}</a>
</nav>
<section class="sheet-content">
<div class="tab combat flexcol" data-group="primary" data-tab="combat">
{{> "systems/midgard5/templates/sheets/npc/combat.hbs"}}
</div>
<div class="tab properties flexcol" data-group="primary" data-tab="properties">
{{> "systems/midgard5/templates/sheets/npc/properties.hbs"}}
</div>
<div class="tab description flexcol" data-group="primary" data-tab="description">
{{> "systems/midgard5/templates/sheets/npc/description.hbs"}}
</div>
</section>
</form>

View File

@ -0,0 +1,117 @@
<div class="flexbox">
<div class="flexcolumn-1">
<div class="flexpart-header"><img src="icons/skills/melee/maneuver-sword-katana-yellow.webp" class="flexpart-icon">{{localize "midgard5.attributes"}}</div>
<div class="flexpart">
<div class="attributes">
{{> "systems/midgard5/templates/sheets/npc/attribute.hbs" attributeId="st" attribute=data.attributes.st}}
{{> "systems/midgard5/templates/sheets/npc/attribute.hbs" attributeId="gs" attribute=data.attributes.gs}}
{{> "systems/midgard5/templates/sheets/npc/attribute.hbs" attributeId="gw" attribute=data.attributes.gw}}
{{> "systems/midgard5/templates/sheets/npc/attribute.hbs" attributeId="ko" attribute=data.attributes.ko}}
{{> "systems/midgard5/templates/sheets/npc/attribute.hbs" attributeId="in" attribute=data.attributes.in}}
{{> "systems/midgard5/templates/sheets/npc/attribute.hbs" attributeId="zt" attribute=data.attributes.zt}}
{{> "systems/midgard5/templates/sheets/npc/attribute.hbs" attributeId="au" attribute=data.attributes.au}}
{{> "systems/midgard5/templates/sheets/npc/attribute.hbs" attributeId="pa" attribute=data.attributes.pa}}
{{> "systems/midgard5/templates/sheets/npc/attribute.hbs" attributeId="wk" attribute=data.attributes.wk}}
{{> "systems/midgard5/templates/sheets/npc/attribute.hbs" attributeId="git" attribute=data.attributes.git}}
<div class="sheet-npc">
<div class="attribute-header">{{localize "midgard5.movementRange"}}</div>
<div class="attribute-value"><input name="data.movement" type="text" value="{{data.movement}}" data-dtype="Number" /></div>
</div>
<div class="sheet-npc">
<div class="attribute-header">{{localize "midgard5.exp-overall"}}</div>
<div class="attribute-value"><input name="data.es" type="text" value="{{data.es}}" data-dtype="Number" /></div>
</div>
<div class="sheet-npc">
<div class="attribute-header">{{localize "midgard5.actor-lp-short"}} {{localize "midgard5.maximum"}}</div>
<div class="attribute-value"><input name="data.lp.max" type="text" value="{{data.lp.max}}" data-dtype="Number" /></div>
</div>
<div class="sheet-npc">
<div class="attribute-header">{{localize "midgard5.actor-ap-short"}} {{localize "midgard5.maximum"}}</div>
<div class="attribute-value"><input name="data.ap.max" type="text" value="{{data.ap.max}}" data-dtype="Number" /></div>
</div>
<div class="sheet-npc">
<div class="attribute-header">{{localize "midgard5.magicUsing"}}</div>
<div class="attribute-value"><input id="data.info.magicUsing" type="checkbox" name="data.info.magicUsing" {{checked data.info.magicUsing}}></div>
</div>
</div>
</div>
</div>
<div class="flexcolumn-2">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/sundries/gaming/dice-pair-white-green.webp" class="flexpart-icon">{{localize "midgard5.skills"}}</div>
<input id="data.info.showUnlearned" class="checkbox" type="checkbox" name="data.info.showUnlearned" {{checked data.info.showUnlearned}} style="float: right;">
<label for="data.info.showUnlearned" style="font-size: small; font-weight: normal; font-style: italic; float: right;">{{localize "midgard5.showUnlearned"}}&nbsp;</label>
<table>
<thead>
<tr>
<th class="title">{{localize "midgard5.skills"}}</th>
<th class="title">{{localize "midgard5.ew"}}</th>
<th class="title"><img src="/icons/svg/d20.svg" class="table-icon"></th>
<th><a class="title add-general-skill"><i class="fa-regular fa-plus"></i></a></th>
</tr>
</thead>
<tbody>
{{#each data.calc.skills.general as |skill skillId|}}
<tr data-item-id="{{skillId}}" class="item">
<td class="padding edit-item">{{skill.label}}</td>
<td class="fixed-value"><input type="text" value="{{skill.fw}}" data-dtype="Number" /></td>
<td><button class="roll-button roll-learned-button"></button></td>
<td><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/each}}
{{#unless (not data.info.showUnlearned)}}
{{#each data.skills.general as |skill key|}}
{{#unless (isSkillInList (localizeMidgard key) ../actor.system.calc.skills.general) }}
<tr data-skill="{{key}}">
<td class="padding" style="font-style: italic;">{{localizeMidgard key}}</td>
<td class="fixed-value"><input type="text" value="{{skill.fw}}" data-dtype="Number" /></td>
<td><button class="roll-button roll-general-button"></button></td>
<td><a class="learn-button" title="Learn Skill"><i class="fa-regular fa-plus"></i></a></td>
</tr>
{{/unless}}
{{/each}}
{{/unless}}
</tbody>
</table>
</div>
</div>
<div class="flexcolumn-2">
<div class="flexpart">
<div class="flexpart-header"><img src="icons/tools/hand/scale-balances-merchant-brown.webp" class="flexpart-icon">{{localize "midgard5.gear"}}</div>
<table>
<thead class="theader">
<tr>
<th class="title"><img src="/icons/svg/eye.svg" class="table-icon"></th>
<th class="title">{{localize "TYPES.Item.item"}}</th>
<th class="title center">{{localize "midgard5.item-quantity"}}</th>
<th class="title center">{{localize "midgard5.item-value"}}</th>
<td><a class="title add-item"><i class="fa-regular fa-plus"></i></a></th>
</tr>
</thead>
<tbody class="items-list">
<tr height = 10px></tr>
{{#each data.calc.gear.items as |item itemId|}}
<tr data-item-id="{{itemId}}" class="item">
<td class="flexpart-img"><img src={{item.icon}} class="flexpart-icon"></td>
<td class="padding">
<span class="edit-item">{{item.label}}</span>
</td>
<td>
<i class="fa fa-minus-circle quantity-decrease" style="cursor: pointer"></i>
<span>{{item.quantity}}</span>
<i class="fa fa-plus-circle quantity-increase" style="cursor: pointer"></i>
</td>
<td style="text-align: start">
{{#unless (or (eq item.value 0) (eq item.currency ""))}}
<span class="spell-process">{{item.value}} {{localize (m5concat "midgard5.currency-" item.currency)}}</span>
{{/unless}}
</td>
<td><a class="item-delete" title="Delete Item"><i class="fas fa-trash"></i></a></td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</div>
</div>

View File

@ -0,0 +1,60 @@
<table>
<thead>
<tr>
<th>Mods</th>
<th></th>
<th></th>
<th><button class="add-mod">+</button></th>
<th></th>
</tr>
</thead>
<tbody class="items-list">
{{#each mods as |mod modId|}}
<tr data-mod-id="{{modId}}" class="item">
<td>
<select class="select-mod-type" name="data.mods.{{modId}}.type" data-type="String">
{{#select mod.type}}
<option value="attribute">{{localize "midgard5.attribute"}}</option>
<option value="stat">{{localize "midgard5.bonus"}}</option>
<option value="skill">{{localize "midgard5.skill"}}</option>
{{/select}}
</select>
</td>
<td>
<select class="select-id" name="data.mods.{{modId}}.id" data-type="String">
{{#select mod.id}}
<option value="">{{localize "midgard5.no-skill"}}</option>
{{#each (lookup ../calc.mods modId) as |name key|}}
<option value="{{key}}">{{name}}</option>
{{/each}}
{{/select}}
</select>
</td>
<td>
<select class="select-mod-operation" name="data.mods.{{modId}}.operation" data-type="String">
{{#select mod.operation}}
{{#if (eq mod.type "attribute")}}
<option value="add100">{{localize "midgard5.mod-operation-add100"}}</option>
<option value="roll">{{localize "midgard5.mod-operation-roll"}}</option>
{{/if}}
<option value="add">{{localize "midgard5.mod-operation-add"}}</option>
<option value="set">{{localize "midgard5.mod-operation-set"}}</option>
<option value="fixed">{{localize "midgard5.mod-operation-fixed"}}</option>
<option value="subtract">{{localize "midgard5.mod-operation-subtract"}}</option>
<option value="multiply">{{localize "midgard5.mod-operation-multiply"}}</option>
<option value="division">{{localize "midgard5.mod-operation-division"}}</option>
{{/select}}
</select>
</td>
<td>
<input name="data.mods.{{modId}}.value" type="number" value="{{mod.value}}" data-dtype="Number" />
</td>
<td class="fixed-value"><a class="mod-delete" title="Delete Roll"><i class="fas fa-trash"></i></a></td>
</tr>
{{/each}}
</tbody>
</table>