diff --git a/lang/de.json b/lang/de.json index 21f3728..3477170 100644 --- a/lang/de.json +++ b/lang/de.json @@ -5,6 +5,7 @@ "ITEM.TypeItem": "Gegenstand", "ITEM.TypeWeapon": "Waffe", + "ITEM.TypeDefensiveWeapon": "Verteidigungswaffe", "ITEM.TypeArmor": "Rüstung", "ITEM.TypeSpell": "Zauber", @@ -25,7 +26,9 @@ "midgard5.item-ismagic": "Ist Magisch", "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", @@ -48,6 +51,7 @@ "midgard5.aktuell": "Akt.", "midgard5.maximum": "Max.", "midgard5.attrvalue": "Wert", + "midgard5.movementRange": "Bewegungsweite", "midgard5.base_values": "Grundwerte", "midgard5.skills": "Fertigkeiten", @@ -127,8 +131,11 @@ "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", @@ -144,10 +151,51 @@ "midgard5.language": "Sprache", "midgard5.weapon-skill": "Waffenfertigkeit", "midgard5.unlearned-skill": "Ungelernte Fertigkeit", + "midgard5.innate-ability": "Angeborene Fähigkeit", "midgard5.base-damage": "Grundschaden", "midgard5.defensive-weapon": "Verteidigungswaffe", "midgard5.no-skill": "Keine Fertigkeit", "midgard5.magic": "magisch", - "midgard5.rangedWeapon": "Schusswaffe" + "midgard5.rangedWeapon": "Schusswaffe", + + "midgard5.pw": "Prüfwurf", + "midgard5.attack": "Angriff", + "midgard5.damage": "Schaden", + + "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", + + "midgard5.spell-type-gedanke": "Gedanke", + "midgard5.spell-type-geste": "Geste", + "midgard5.spell-type-wort": "Wort", + + "midgard5.spell-target-umgebung": "Umgebung", + "midgard5.spell-target-geist": "Geist", + "midgard5.spell-target-koerper": "Körper", + + "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" } diff --git a/packs/actors/blaupause-spielfiguren/nsc_nicht_verbunden.json b/packs/actors/blaupause-spielfiguren/nsc_nicht_verbunden.json deleted file mode 100644 index 9f0df8a..0000000 --- a/packs/actors/blaupause-spielfiguren/nsc_nicht_verbunden.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "_id": "d9fKKyYxVSnUOsE4", - "name": "Blaupause NSpF - nicht verbunden", - "permission": { - "default": 0, - "CBq5YXAqbO7HoJ03": 3 - }, - "type": "npc", - "data": { - "lp": { - "value": 15, - "min": 0, - "max": 15 - }, - "ap": { - "value": 20, - "min": 0, - "max": 20 - }, - "st": { - "value": 50, - "bonus": 0 - }, - "ge": { - "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 - }, - "description": " " - }, - "sort": 100001, - "flags": { - "core": { - "sourceId": "Compendium.midgard5.blaupause-spielfiguren.UZ24J3Izksd0gNfR" - } - }, - "img": "icons/svg/wing.svg", - "token": { - "flags": {}, - "name": "Blaupause NSpF - nicht verbunden", - "displayName": 30, - "img": "icons/svg/wing.svg", - "tint": "", - "width": 1, - "height": 1, - "scale": 1, - "mirrorX": false, - "mirrorY": false, - "lockRotation": false, - "rotation": 0, - "vision": true, - "dimSight": 0, - "brightSight": 0, - "dimLight": 0, - "brightLight": 0, - "sightAngle": 360, - "lightAngle": 360, - "lightColor": "", - "lightAlpha": 1, - "lightAnimation": { - "type": "", - "speed": 5, - "intensity": 5 - }, - "actorId": "d9fKKyYxVSnUOsE4", - "actorLink": false, - "disposition": -1, - "displayBars": 50, - "bar1": { - "attribute": "lp" - }, - "bar2": { - "attribute": "ap" - }, - "randomImg": false - }, - "items": [], - "effects": [] -} \ No newline at end of file diff --git a/packs/actors/blaupause-spielfiguren/nsc_verbunden.json b/packs/actors/blaupause-spielfiguren/nsc_verbunden.json deleted file mode 100644 index 0f401a6..0000000 --- a/packs/actors/blaupause-spielfiguren/nsc_verbunden.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "_id": "bqttz8gtZyKV7t30", - "name": "Blaupause NSpF - verbunden", - "permission": { - "default": 0, - "CBq5YXAqbO7HoJ03": 3 - }, - "type": "npc", - "data": { - "lp": { - "value": 15, - "min": 0, - "max": 15 - }, - "ap": { - "value": 20, - "min": 0, - "max": 20 - }, - "st": { - "value": 50, - "bonus": 0 - }, - "ge": { - "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 - }, - "description": " " - }, - "sort": 100001, - "flags": { - "core": { - "sourceId": "Compendium.midgard5.blaupause-spielfiguren.UZ24J3Izksd0gNfR" - } - }, - "img": "icons/svg/wing.svg", - "token": { - "flags": {}, - "name": "Blaupause NSpF - verbunden", - "displayName": 30, - "img": "icons/svg/wing.svg", - "tint": "", - "width": 1, - "height": 1, - "scale": 1, - "mirrorX": false, - "mirrorY": false, - "lockRotation": false, - "rotation": 0, - "vision": true, - "dimSight": 0, - "brightSight": 0, - "dimLight": 0, - "brightLight": 0, - "sightAngle": 360, - "lightAngle": 360, - "lightColor": "", - "lightAlpha": 1, - "lightAnimation": { - "type": "", - "speed": 5, - "intensity": 5 - }, - "actorId": "bqttz8gtZyKV7t30", - "actorLink": true, - "disposition": -1, - "displayBars": 50, - "bar1": { - "attribute": "lp" - }, - "bar2": { - "attribute": "ap" - }, - "randomImg": false - }, - "items": [], - "effects": [] -} \ No newline at end of file diff --git a/packs/actors/blaupause-spielfiguren/spieler.json b/packs/actors/blaupause-spielfiguren/spieler.json deleted file mode 100644 index 0b52dcb..0000000 --- a/packs/actors/blaupause-spielfiguren/spieler.json +++ /dev/null @@ -1,111 +0,0 @@ -{ - "_id": "R41aDRCMdLzXuTwY", - "name": "Blaupause Spielerfigur", - "permission": { - "default": 0, - "CBq5YXAqbO7HoJ03": 3 - }, - "type": "character", - "data": { - "lp": { - "value": 15, - "min": 0, - "max": 15 - }, - "ap": { - "value": 20, - "min": 0, - "max": 20 - }, - "st": { - "value": 50, - "bonus": 0 - }, - "ge": { - "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 - }, - "description": " ", - "es": 0, - "ep": 0, - "gg": 0, - "sg": 0, - "gp": 2 - }, - "sort": 100001, - "flags": { - "core": { - "sourceId": "Compendium.world.blaupause-spielfiguren.t9eB2RdE1n9wV8eq" - } - }, - "img": "icons/svg/aura.svg", - "token": { - "flags": {}, - "name": "Blaupause Spielfigur", - "displayName": 30, - "img": "icons/svg/aura.svg", - "tint": "", - "width": 1, - "height": 1, - "scale": 1, - "mirrorX": false, - "mirrorY": false, - "lockRotation": false, - "rotation": 0, - "vision": true, - "dimSight": 0, - "brightSight": 0, - "dimLight": 0, - "brightLight": 0, - "sightAngle": 360, - "lightAngle": 360, - "lightColor": "", - "lightAlpha": 1, - "lightAnimation": { - "type": "", - "speed": 5, - "intensity": 5 - }, - "actorId": "R41aDRCMdLzXuTwY", - "actorLink": true, - "disposition": 1, - "displayBars": 50, - "bar1": { - "attribute": "lp" - }, - "bar2": { - "attribute": "ap" - }, - "randomImg": false - }, - "items": [], - "effects": [] -} \ No newline at end of file diff --git a/packs/items/blaupause-gegenstaende/fertigkeit.json b/packs/items/blaupause-gegenstaende/fertigkeit.json new file mode 100644 index 0000000..209f09f --- /dev/null +++ b/packs/items/blaupause-gegenstaende/fertigkeit.json @@ -0,0 +1,69 @@ +{ + "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", + "type": "ew", + "label": "EW" + } + }, + "output": "" + }, + "calc": {} + }, + "effects": [], + "folder": null, + "sort": 0, + "permission": { + "default": 0, + "XD0IpWT6bN4AJiYQ": 3 + }, + "_id": "4N0IgVDj1eee0hSB" +} \ No newline at end of file diff --git a/packs/items/blaupause-gegenstaende/fähigkeit.json b/packs/items/blaupause-gegenstaende/fähigkeit.json new file mode 100644 index 0000000..c254031 --- /dev/null +++ b/packs/items/blaupause-gegenstaende/fähigkeit.json @@ -0,0 +1,74 @@ +{ + "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 + }, + "flags": { + "core": { + "sourceId": "Item.ieQ6JMEyOoF7n0qy" + } + }, + "_id": "nkMkMFNDSdvlP1Jt" +} \ No newline at end of file diff --git a/packs/items/blaupause-gegenstaende/sprache.json b/packs/items/blaupause-gegenstaende/sprache.json new file mode 100644 index 0000000..b8c42e2 --- /dev/null +++ b/packs/items/blaupause-gegenstaende/sprache.json @@ -0,0 +1,69 @@ +{ + "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.fw + @i.calc.bonus", + "type": "ew", + "label": "EW" + } + }, + "output": "" + }, + "calc": {} + }, + "effects": [], + "folder": null, + "sort": 0, + "permission": { + "default": 0, + "XD0IpWT6bN4AJiYQ": 3 + }, + "_id": "rDN14z3lNJISWTdO" +} \ No newline at end of file diff --git a/packs/items/blaupause-gegenstaende/verteidigungswaffe.json b/packs/items/blaupause-gegenstaende/verteidigungswaffe.json new file mode 100644 index 0000000..d18521b --- /dev/null +++ b/packs/items/blaupause-gegenstaende/verteidigungswaffe.json @@ -0,0 +1,42 @@ +{ + "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 + @c.calc.stats.defenseBonus + @i.stats.defenseBonus", + "type": "ew", + "label": "Abwehr" + } + }, + "output": "" + }, + "calc": {}, + "damageBase": "" + }, + "effects": [], + "folder": null, + "sort": 0, + "permission": { + "default": 0, + "XD0IpWT6bN4AJiYQ": 3 + }, + "_id": "BNAoHN0vHfcwNUTl" +} \ No newline at end of file diff --git a/packs/items/blaupause-gegenstaende/waffe.json b/packs/items/blaupause-gegenstaende/waffe.json index e9cd2c6..6ab308a 100644 --- a/packs/items/blaupause-gegenstaende/waffe.json +++ b/packs/items/blaupause-gegenstaende/waffe.json @@ -1,27 +1,48 @@ { - "_id": "WH2b4Tv630iuyAGJ", - "name": "Blaupause Schwert", - "permission": { - "default": 0, - "CBq5YXAqbO7HoJ03": 3 - }, + "name": "Waffe", "type": "weapon", "img": "icons/svg/item-bag.svg", "data": { - "description": "Ein langes Stück Metall mit einem spitzen Ende.", - "damageBonus": 0, - "attackBonus": 0, - "defenseBonus": 0, - "movementBonus": 0, - "resistanceMind": 0, - "resistanceBody": 0, - "spellBonus": 0, - "skill": "", - "quantity": 1, - "value": 100, - "onbody": false, - "magic": false + "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 + @i.stats.attackBonus", + "type": "ew", + "label": "Angriff" + }, + "1": { + "formula": "@i.damageBase + @i.stats.damageBonus + @c.calc.stats.damageBonus", + "type": "dmg", + "label": "Schaden" + } + }, + "output": "" + }, + "calc": {} }, "effects": [], - "flags": {} - } \ No newline at end of file + "folder": null, + "sort": 0, + "permission": { + "default": 0, + "XD0IpWT6bN4AJiYQ": 3 + }, + "_id": "uGQJ4VPhh135e79a" +} \ No newline at end of file diff --git a/packs/items/blaupause-gegenstaende/waffenfertigkeit.json b/packs/items/blaupause-gegenstaende/waffenfertigkeit.json new file mode 100644 index 0000000..212decc --- /dev/null +++ b/packs/items/blaupause-gegenstaende/waffenfertigkeit.json @@ -0,0 +1,69 @@ +{ + "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.fw + @i.calc.bonus", + "type": "ew", + "label": "EW" + } + }, + "output": "" + }, + "calc": {} + }, + "effects": [], + "folder": null, + "sort": 0, + "permission": { + "default": 0, + "XD0IpWT6bN4AJiYQ": 3 + }, + "_id": "1E4XHTGZlned2ofY" +} \ No newline at end of file diff --git a/source/PreloadTemplates.ts b/source/PreloadTemplates.ts index 2a0833f..56ed6dd 100644 --- a/source/PreloadTemplates.ts +++ b/source/PreloadTemplates.ts @@ -8,7 +8,9 @@ const preloadTemplates = async (): Promise[]> = const templates: Array = [ "sheets/character/base_values.hbs", "sheets/character/skills.hbs", - "sheets/character/gear.hbs" + "sheets/character/gear.hbs", + "sheets/character/spells.hbs", + "chat/roll-m5.hbs" ] return loadTemplates(templates.map(s => rootPath + s)) } diff --git a/source/index.ts b/source/index.ts index cbb959c..5d9465f 100644 --- a/source/index.ts +++ b/source/index.ts @@ -9,14 +9,23 @@ import { M5Item } from "./module/items/M5Item" Hooks.once("init", async () => { Logger.log("M5 | Initialisierung Midgard 5") - Handlebars.registerHelper("eq", (lhs: any, rhs: any) => { - return lhs === rhs - }) - 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) + }) + + // static concat(...values) { + // const options = values.pop(); + // const join = options.hash?.join || ""; + // return new Handlebars.SafeString(values.join(join)); + // } + Handlebars.registerHelper("localizeMidgard", (str: string) => { const template = Handlebars.compile("{{localize value}}") return template({ @@ -42,6 +51,27 @@ Hooks.once("init", async () => { 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.data.items.get(itemId).data.data + path.split(".").forEach(p => { + if (obj) + obj = obj[p] + }) + return `${obj}` + }) + + Handlebars.registerHelper("icon", (relpath: string) => { + return `systems/midgard5/assets/icons/${relpath}` + }) + // Default Sheet für Items definieren und das Standardsheet deaktivieren Items.unregisterSheet("core", ItemSheet) Items.registerSheet("midgard5", M5ItemSheet, { makeDefault: true }) diff --git a/source/module/M5Base.ts b/source/module/M5Base.ts index 6c2b4d0..f3df0e4 100644 --- a/source/module/M5Base.ts +++ b/source/module/M5Base.ts @@ -19,8 +19,32 @@ export interface M5Attribute { } export interface M5RollData { - c: any, - i: any, - rolls: any, - res: any + c: any + i: any + iType: string + rolls: {} + res: { + label: string + } } + +export interface M5RollResult { + formula: string + label: string + type: string + + total: number + totalStr: string + result: string + dice: {} + css: string +} + +export enum M5EwResult { + TBD = "", + FUMBLE = "roll-ew-result-fumble", + CRITICAL = "roll-ew-result-critical", + HIGH = "roll-ew-result-high", + FAIL = "roll-ew-result-fail", + PASS = "roll-ew-result-pass" +} \ No newline at end of file diff --git a/source/module/actors/M5Character.ts b/source/module/actors/M5Character.ts index 02ddf05..2c52cb0 100644 --- a/source/module/actors/M5Character.ts +++ b/source/module/actors/M5Character.ts @@ -25,10 +25,12 @@ export interface M5CharacterCalculatedData { resistanceBody: number spellCasting: number brawl: number + brawlEw: number poisonResistance: number enduranceBonus: number } skills: { + innate: {} general: {} combat: {} language: {} @@ -36,9 +38,11 @@ export interface M5CharacterCalculatedData { } gear: { weapons: {} + defensiveWeapons: {} armor: {} items: {} } + spells: {} } export class M5Character extends Actor { @@ -68,7 +72,7 @@ export class M5Character extends Actor { return -2 } - derivedData(skipSkills: boolean, skipWeapons: boolean): M5CharacterCalculatedData { + derivedData(skip: { skills?: boolean, weapons?: boolean, defensiveWeapons?: boolean, armor?: boolean, items?: boolean, spells?: boolean } = {} ): M5CharacterCalculatedData { let ret: M5CharacterCalculatedData = { level: 0, attributes: { @@ -93,10 +97,12 @@ export class M5Character extends Actor { resistanceBody: 0, spellCasting: 0, brawl: 0, + brawlEw: 0, poisonResistance: 0, enduranceBonus: 0 }, skills: { + innate: {}, general: {}, combat: {}, language: {}, @@ -104,9 +110,11 @@ export class M5Character extends Actor { }, gear: { weapons: {}, + defensiveWeapons: {}, armor: {}, items: {} - } + }, + spells: {} } as M5CharacterCalculatedData const context = (this as any).data @@ -143,10 +151,11 @@ export class M5Character extends Actor { ret.stats.resistanceBody = ret.stats.defense + 1 ret.stats.spellCasting = (data.info.magicUsing ? M5Character.spellCastingFromLevel(ret.level) : 3) + ret.attributes.zt.bonus ret.stats.brawl = Math.floor((ret.attributes.st.value + ret.attributes.gw.value) / 20) + ret.stats.brawlEw = ret.stats.brawl + ret.stats.attackBonus ret.stats.poisonResistance = 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) - if (!skipSkills) { + if (!skip.skills) { context.items?.filter(item => item.data.type === "skill").forEach(item => { item.prepareDerivedData() const skillMap = ret.skills[item.data.data.type] @@ -159,7 +168,7 @@ export class M5Character extends Actor { }) } - if (!skipWeapons) { + if (!skip.weapons) { context.items?.filter(item => item.data.type === "weapon").forEach(item => { item.prepareDerivedData() @@ -175,25 +184,91 @@ export class M5Character extends Actor { ret.gear.weapons[item.data._id] = { label: label, skillId: item.data.data.skillId, - defensive: item.data.data.defensive, magic: item.data.data.magic, calc: item.data.data.calc } }) } + if (!skip.defensiveWeapons) { + context.items?.filter(item => item.data.type === "defensiveWeapon").forEach(item => { + item.prepareDerivedData() + + let label = item.data.name + if (item.data.data.magic) { + label += "*(" + + (item.data.data.stats.defenseBonus < 0 ? "" : "+") + + item.data.data.stats.defenseBonus + ")" + } + + ret.gear.defensiveWeapons[item.data._id] = { + label: label, + skillId: item.data.data.skillId, + magic: item.data.data.magic, + calc: item.data.data.calc + } + }) + } + + if (!skip.armor) { + context.items?.filter(item => item.data.type === "armor").forEach(item => { + item.prepareDerivedData() + + let label = item.data.name + if (item.data.data.magic) { + label += "*" + } + + ret.gear.armor[item.data._id] = { + label: label, + magic: item.data.data.magic, + calc: item.data.data.calc + } + }) + } + + if (!skip.items) { + context.items?.filter(item => item.data.type === "item").forEach(item => { + item.prepareDerivedData() + + let label = item.data.name + if (item.data.data.magic) { + label += "*" + } + + ret.gear.items[item.data._id] = { + label: label, + magic: item.data.data.magic, + calc: item.data.data.calc + } + }) + } + + if (!skip.spells) { + context.items?.filter(item => item.data.type === "spell").forEach(item => { + item.prepareDerivedData() + + ret.spells[item.data._id] = { + label: item.data.name, + process: "midgard5.spell-process-" + item.data.data.process, + calc: item.data.data.calc + } + }) + } + return ret } prepareDerivedData() { const context = (this as any).data - context.data.calc = this.derivedData(false, false) + context.data.calc = this.derivedData({}) } override getRollData(): any { return { c: (this as any).data.data, i: null, + iType: null, rolls: {}, res: {} } as M5RollData diff --git a/source/module/items/M5Item.ts b/source/module/items/M5Item.ts index f932e98..4e6cc4f 100644 --- a/source/module/items/M5Item.ts +++ b/source/module/items/M5Item.ts @@ -1,5 +1,6 @@ import { M5Character } from "../actors/M5Character" -import { M5RollData, M5Skill } from "../M5Base" +import { M5RollData, M5RollResult, M5Skill } from "../M5Base" +import { M5Roll } from "../rolls/M5Roll" export class M5Item extends Item { static readonly SKILL = "skill" @@ -13,22 +14,21 @@ export class M5Item extends Item { if (context.type === "skill") { calc.bonus = 0 - if (context.data.attribute && context.data.attribute !== "") { + if (context.data?.attribute && context.data?.attribute !== "" && character) { const attribute = character.attribute(context.data.attribute) calc.bonus += M5Character.attributeBonus(attribute) } - if (context._id === actor.data?.data?.skills.preferredCombatSkill) { - calc.bonus += 2 - } - calc.ew = context.data.fw + calc.bonus } else if (context.type === "weapon") { - calc.ew = context.data.stats.attackBonus + calc.fw = 0 + calc.bonus = 0 + calc.special = context.data.special ? 2 : 0 + calc.ew = calc.special + context.data.stats.attackBonus calc.combatSkills = null if (actor) { - const actorCalc = character.derivedData(false, true) + const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true }) calc.ew += actorCalc.stats.attackBonus const skill = character.getSkill(context.data.skillId) as any @@ -37,10 +37,41 @@ export class M5Item extends Item { skill.prepareDerivedData() const skillData = skill.data.data calc.ew += skillData.calc.ew + calc.bonus += skillData.calc.bonus + calc.fw += skillData.fw } calc.combatSkills = actorCalc.skills.combat } + } else if (context.type === "defensiveWeapon") { + calc.fw = 0 + calc.bonus = 0 + calc.special = context.data.special ? 2 : 0 + calc.ew = calc.special + context.data.stats.defenseBonus + calc.combatSkills = null + + if (actor) { + const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true }) + calc.ew += actorCalc.stats.defense + actorCalc.stats.defenseBonus + + const skill = character.getSkill(context.data.skillId) as any + //console.log("M5Item.prepareDerivedData:weapon", context.data, skill?.data?.data) + if (skill) { + skill.prepareDerivedData() + const skillData = skill.data.data + calc.ew += skillData.calc.ew + calc.bonus += skillData.calc.bonus + calc.fw += skillData.fw + } + + calc.combatSkills = actorCalc.skills.combat + } + } else if (context.type === "spell") { + calc.ew = context.data.bonus + if (actor) { + const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true }) + calc.ew += actorCalc.stats.spellCasting + } } } @@ -51,11 +82,13 @@ export class M5Item extends Item { let ret: M5RollData = actor?.getRollData() ?? { c: null, i: null, + iType: null, rolls: {}, res: {} } ret.i = context.data + ret.iType = context.type return ret } @@ -71,21 +104,21 @@ export class M5Item extends Item { const formulaNames = item.data.rolls?.formulas ? Object.keys(item.data.rolls.formulas) : [] if (formulaNames.length > 0) { const rollData = this.getRollData() - let ret = [] - formulaNames.forEach(formulaName => { const formula = item.data.rolls.formulas[formulaName] - const roll = new Roll(formula.formula, rollData) - - roll.toMessage({ - speaker: speaker, - rollMode: rollMode, - flavor: label, - }) - ret.push(roll) + rollData.rolls[formulaName] = { + formula: formula.formula, + label: formula.label, + type: formula.type, + result: "", + total: 0, + totalStr: "", + dice: {} + } as M5RollResult }) - - return ret + + const roll = new M5Roll(rollData, this.actor, item.name) + return roll.toMessage() } else { ChatMessage.create({ speaker: speaker, diff --git a/source/module/rolls/M5Roll.ts b/source/module/rolls/M5Roll.ts new file mode 100644 index 0000000..90ab2db --- /dev/null +++ b/source/module/rolls/M5Roll.ts @@ -0,0 +1,160 @@ +import { Evaluated } from "@league-of-foundry-developers/foundry-vtt-types/src/foundry/client/dice/roll"; +import { M5Character } from "../actors/M5Character"; +import { M5EwResult, M5RollData, M5RollResult } from "../M5Base"; + +export class M5Roll { // extends Roll + static readonly TEMPLATE_PATH = "systems/midgard5/templates/chat/roll-m5.hbs" + + public _evaluated: boolean = false + public _total: number = 0 + public pool: PoolTerm = null + + constructor(public data: M5RollData, public actor: any, public label: string) { + //super(null) + //this.data = rollData + } + + // @ts-ignore + //override evaluate(options?: InexactPartial): Evaluated> | Promise>> { + evaluate() { + const rollNames = Object.keys(this.data.rolls) + const rolls = rollNames.map(rollName => { + const formula = this.data.rolls[rollName] + const roll = new Roll(formula.formula, this.data) + return roll + }) + + this.pool = PoolTerm.fromRolls(rolls) + return this.pool.evaluate({ async: true }).then(results => { + this._total = 0 + + results.rolls.forEach((roll, index) => { + const rollResult = this.data.rolls[index.toString()] as M5RollResult + rollResult.result = roll.result + rollResult.total = roll.total + rollResult.totalStr = roll.total.toString() + + this._total += roll.total + + let rowRes = M5EwResult.TBD + roll.dice.forEach((d, dIndex) => { + rollResult.dice[dIndex.toString()] = d.total + + if (rowRes === M5EwResult.TBD && dIndex === 0) { + 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 + } else if (rollResult.type === "pw") { + if (d.total === 1) + rowRes = M5EwResult.FUMBLE + else if (d.total === 20) + rowRes = M5EwResult.CRITICAL + } + } + }) + + if (rollResult.type === "ew") { + if (roll.total < 20) { + if (rowRes === M5EwResult.TBD || rowRes === M5EwResult.HIGH) + rowRes = M5EwResult.FAIL + } else { + if (rowRes === M5EwResult.TBD) + rowRes = M5EwResult.PASS + } + } else if (rollResult.type === "pw") { + if (roll.total < 0) { + if (rowRes === M5EwResult.TBD) + rowRes = M5EwResult.FAIL + } else { + if (rowRes === M5EwResult.TBD) + rowRes = M5EwResult.PASS + } + } + rollResult.css = rowRes + }) + + this.data.res.label = this.label + + this._evaluated = true + return this + }) + } + + async render(): Promise { + return renderTemplate(M5Roll.TEMPLATE_PATH, this.data) + } + + async toMessage() { + if (!this._evaluated) + await this.evaluate() + + const rMode = (game as Game).settings.get("core", "rollMode") + + 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]) + } + + 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", + type: "pw", + 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`)) + } + + static brawl(actor: any) { + const rollData = actor.getRollData() as M5RollData + rollData.i = { + attackBonus: 0, + damageBonus: 0 + } + + rollData.rolls["0"] = { + formula: "1d20 + @c.calc.stats.brawl + @c.calc.stats.attackBonus + @i.attackBonus", + type: "ew", + label: (game as Game).i18n.localize("midgard5.attack"), + result: "", + total: 0, + totalStr: "", + dice: {}, + css: "" + } as M5RollResult + + rollData.rolls["1"] = { + formula: "1d6 - 4 + @c.calc.stats.damageBonus + @i.damageBonus", + type: "dmg", + label: (game as Game).i18n.localize("midgard5.damage"), + result: "", + total: 0, + totalStr: "", + dice: {}, + css: "" + } as M5RollResult + + return new M5Roll(rollData, actor, (game as Game).i18n.localize("midgard5.brawl")) + } +} diff --git a/source/module/sheets/M5CharacterSheet.ts b/source/module/sheets/M5CharacterSheet.ts index c56b34a..3865655 100644 --- a/source/module/sheets/M5CharacterSheet.ts +++ b/source/module/sheets/M5CharacterSheet.ts @@ -2,13 +2,14 @@ import Logger from "../../utils/Logger" import { M5Character } from "../actors/M5Character" import { M5Item } from "../items/M5Item" import { M5SkillLearned, 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: 600, + width: 800, height: 800, classes: ["midgard5", "sheet", "character"], tabs: [{ navSelector: ".sheet-navigation", contentSelector: ".sheet-content", initial: "base_values" }] @@ -37,29 +38,28 @@ export default class M5CharacterSheet extends ActorSheet { override activateListeners(html: JQuery) { super.activateListeners(html) + html.find(".roll-attribute-button").on("click", async (event) => { + const attributeStr = event.target.dataset["attribute"] + const roll = M5Roll.fromAttribute(this.actor, attributeStr) + console.log("roll-attribute-button", roll) + await roll.toMessage() + }) + html.find(".edit-item").on("click", async (event) => { - const row = event.target.parentElement + let row = event.target.parentElement let itemId = row.dataset["item"] + while (!itemId) { + row = row.parentElement + if (!row) + return + itemId = row.dataset["item"] + } const context = this.actor.data const item = context.items.get(itemId) item.sheet.render(true) }) - html.find(".change-special-combat-skill").on("click", async (event) => { - const row = event.target.parentElement.parentElement - let skillId = row.dataset["item"] - - const actor = this.actor as any - actor.update({ - data: { - skills: { - preferredCombatSkill: skillId - } - } - }) - }) - html.find(".roll-learned-button").on("click", async (event) => { const row = event.target.parentElement.parentElement let skillId = row.dataset["item"] @@ -72,24 +72,6 @@ export default class M5CharacterSheet extends ActorSheet { await item.roll() }) - html.find(".create-skill-button").on("click", async (event) => { - const button = event.target - const skillType = button.dataset["skilltype"] - - const character = this.actor as M5Character - character.createSkill((game as Game).i18n.localize("midgard5.new-skill")).then(skill => { - const item = skill as any - item.update({ - data: { - fw: 5, - attribute: "", - skill: "", - type: skillType - } - }) - }) - }) - html.find(".roll-general-button").on("click", async (event) => { const row = event.target.parentElement.parentElement let skillName = row.dataset["skill"] @@ -151,6 +133,11 @@ export default class M5CharacterSheet extends ActorSheet { await item.roll() }) + html.find(".roll-brawl-button").on("click", async (event) => { + const roll = M5Roll.brawl(this.actor) + await roll.toMessage() + }) + // Drag & Drop const dragDrop = new DragDrop({ dragSelector: ".items-list .item", @@ -175,7 +162,7 @@ export default class M5CharacterSheet extends ActorSheet { const item = this.actor.items.get(li.dataset.itemId) // limit transfer on personal weapons/armour/gear - if (["weapon"].includes(item.data.type)) { + if (["skill", "item", "weapon", "defensiveWeapon", "armor", "spell"].includes(item.data.type)) { const dragData = { type: "Transfer", actorId: this.actor.id, diff --git a/source/style/Character-sheet.less b/source/style/Character-sheet.less index d98cfc0..efc8ad1 100644 --- a/source/style/Character-sheet.less +++ b/source/style/Character-sheet.less @@ -53,6 +53,10 @@ width: 5rem; } + input.fixed { + width: 5rem; + } + .new-skill { font-style: italic; background: rgba(0, 0, 0, 0.3); @@ -62,4 +66,16 @@ background: rgba(255, 255, 255, 0.5); } } + + button.roll-button { + background: url(/icons/svg/d20-black.svg) no-repeat; + background-size: 24px 24px; + width: 26px; + height: 26px; + } + + span.spell-process { + color:rgb(93, 93, 93); + font-style: italic; + } } \ No newline at end of file diff --git a/source/style/roll.less b/source/style/roll.less new file mode 100644 index 0000000..c5b91a7 --- /dev/null +++ b/source/style/roll.less @@ -0,0 +1,76 @@ +.m5-roll { + .roll-title { + text-align: center; + vertical-align: middle; + padding: 0.3rem 0 0.1rem 0; + font-weight: bold; + font-size: 1.3rem; + } + + .roll-spell-details { + text-align: right; + padding-right: 1rem; + font-weight: bold; + } + + .roll-result { + text-align: right; + padding-right: 1rem; + font-weight: bold; + + display: flex; + flex-direction: row; + + .roll-total { + width: 100%; + } + + .roll-detail { + width: 100%; + margin-left: -100%; + } + } + + .roll-row:not( :hover ) { + .roll-total { + visibility: visible; + } + .roll-detail { + visibility: hidden; + } + } + + .roll-row:hover { + .roll-total { + visibility: hidden; + } + .roll-detail { + visibility: visible; + } + } + + .roll-ew-result-fumble { + background-color: rgb(202, 54, 54, 0.5); + color: rgb(255, 255, 255); + } + + .roll-ew-result-critical { + background-color: rgb(202, 197, 54, 0.5); + color: rgb(0, 0, 0); + } + + .roll-ew-result-high { + background-color: rgb(54, 138, 202, 0.5); + color: rgb(255, 255, 255); + } + + .roll-ew-result-fail { + background-color: rgb(117, 63, 131, 0.5); + color: rgb(255, 255, 255); + } + + .roll-ew-result-pass { + background-color: rgb(54, 202, 88, 0.5); + color: rgb(0, 0, 0); + } +} \ No newline at end of file diff --git a/source/system.json b/source/system.json index 62e9a2b..6cdf014 100644 --- a/source/system.json +++ b/source/system.json @@ -19,7 +19,7 @@ { "name": "blaupause-gegenstaende", "label": "Blaupausen für Gegenstände", - "path": "./packs/actors/blaupause-gegenstaende.db", + "path": "./packs/items/blaupause-gegenstaende.db", "type": "Item" }, { diff --git a/source/template.json b/source/template.json index 200ecba..1323f32 100644 --- a/source/template.json +++ b/source/template.json @@ -53,8 +53,6 @@ }, "skills": { "skills": { - "preferredCombatSkill": "", - "innate": {}, "general": { "akrobatik": { "fw": 6, "attribute": "gw", "initial": 8 }, "alchimie": { "fw": 0, "attribute": "in", "initial": 8 }, @@ -107,8 +105,7 @@ "verstellen": { "fw": 3, "attribute": "pa", "initial": 8 }, "wagenlenken": { "fw": 3, "attribute": "gs", "initial": 8 }, "zauberkunde": { "fw": 0, "attribute": "in", "initial": 8 } - }, - "combat": {} + } } } }, @@ -121,7 +118,7 @@ } }, "Item": { - "types": ["skill", "item", "weapon", "armor", "spell"], + "types": ["skill", "item", "weapon", "defensiveWeapon", "armor", "spell"], "templates": { "itemDescription": { "description": "" @@ -150,6 +147,19 @@ "wk": { "short": "midgard5.actor-wk", "long": "midgard5.actor-wk-long" } } }, + "attributeMod": { + "attributeMod": { + "st": 0, + "gs": 0, + "gw": 0, + "ko": 0, + "in": 0, + "zt": 0, + "au": 0, + "pa": 0, + "wk": 0 + } + }, "rollable": { "rolls": { "formulas": {}, @@ -159,6 +169,38 @@ "equippable": { "equippable": false, "equipped": true + }, + "spellSelection": { + "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" + } } }, "skill": { @@ -169,9 +211,10 @@ "type": "general", "rolls": { "formulas": { - "1": { + "0": { "formula": "1d20 + @i.fw + @i.calc.bonus", - "type": "ew" + "type": "ew", + "label": "EW" } }, "output": "" @@ -194,20 +237,39 @@ }, "weapon": { "templates": ["itemDescription", "stats", "equippable"], + "special": false, "magic": false, "ranged": false, - "defensive": false, "skillId": "", "damageBase": "1d6", "rolls": { "formulas": { - "1": { - "formula": "1d20 + @i.calc.ew", - "type": "ew" + "0": { + "formula": "1d20 + @i.calc.fw + @i.calc.bonus + @i.calc.special + @c.calc.stats.attackBonus + @i.stats.attackBonus", + "type": "ew", + "label": "Angriff" }, - "2": { + "1": { "formula": "@i.damageBase + @i.stats.damageBonus + @c.calc.stats.damageBonus", - "type": "dmg" + "type": "dmg", + "label": "Schaden" + } + }, + "output": "" + }, + "calc": {} + }, + "defensiveWeapon": { + "templates": ["itemDescription", "stats", "equippable"], + "special": false, + "magic": false, + "skillId": "", + "rolls": { + "formulas": { + "0": { + "formula": "1d20 + @i.calc.fw + @i.calc.bonus + @i.calc.special + @c.calc.stats.defense + @c.calc.stats.defenseBonus + @i.stats.defenseBonus", + "type": "ew", + "label": "Abwehr" } }, "output": "" @@ -215,7 +277,10 @@ "calc": {} }, "armor": { - "templates": ["itemDescription", "stats", "equippable"], + "templates": ["itemDescription", "stats", "equippable", "attributeMod"], + "magic": false, + "lpProtection": 0, + "apProtection": 0, "rolls": { "formulas": {}, "output": "" @@ -223,9 +288,25 @@ "calc": {} }, "spell": { - "templates": ["itemDescription"], + "templates": ["itemDescription", "spellSelection"], + "bonus": 0, + "type": "", + "process": "", + "ap": 0, + "castDuration": "", + "range": "", + "effectTarget": "", + "effectArea": "", + "effectDuration": "", + "origin": "", "rolls": { - "formulas": {}, + "formulas": { + "0": { + "formula": "1d20 + @c.calc.stats.spellCasting + @i.bonus", + "type": "ew", + "label": "Zaubern" + } + }, "output": "" }, "calc": {} diff --git a/templates/chat/roll-m5.hbs b/templates/chat/roll-m5.hbs new file mode 100644 index 0000000..b131c07 --- /dev/null +++ b/templates/chat/roll-m5.hbs @@ -0,0 +1,58 @@ +
+
+

{{res.label}}

+ + + + {{#if (eq iType "spell")}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{/if}} + + {{#each rolls as |roll index|}} + + + + + {{/each}} + +
{{localize "midgard5.actor-ap"}}{{i.ap}}
{{localize "midgard5.spell-castDuration"}}{{i.castDuration}}
{{localize "midgard5.spell-range"}}{{i.range}}
{{localize "midgard5.spell-effectTarget"}}{{localize (m5concat "midgard5.spell-target-" i.effectTarget)}}
{{localize "midgard5.spell-effectArea"}}{{i.effectArea}}
{{localize "midgard5.spell-effectDuration"}}{{i.effectDuration}}
{{localize "midgard5.spell-origin"}}{{i.origin}}
{{localize "midgard5.spell-type"}}{{localize (m5concat "midgard5.spell-type-" i.type)}}
{{localize "midgard5.spell-process"}}{{localize (m5concat "midgard5.spell-process-" i.process)}}
{{roll.label}} + {{roll.totalStr}} + {{roll.result}} +
+
+
\ No newline at end of file diff --git a/templates/sheets/character/base_values.hbs b/templates/sheets/character/base_values.hbs index a102bce..9136b52 100644 --- a/templates/sheets/character/base_values.hbs +++ b/templates/sheets/character/base_values.hbs @@ -35,34 +35,49 @@ {{localize "midgard5.actor-st-long"}} + + + {{/each}} + + + {{localize "midgard5.brawl"}} + {{data.calc.stats.brawlEw}} + + + + + + + + + + + + + + + {{#each data.calc.gear.defensiveWeapons as |item itemId|}} + + + {{/each}}
{{localize "ITEM.TypeDefensiveWeapon"}}{{localize "midgard5.ew"}}
{{item.label}}{{item.calc.ew}}
+ + + + + + + + + + + + + + + {{#each data.calc.gear.armor as |item itemId|}} + + + + + + + + + + {{/each}} + +
{{localize "ITEM.TypeArmor"}}{{localize "midgard5.actor-lp-short"}}{{localize "midgard5.actor-ap-short"}}{{localize "midgard5.attackBonus-short"}}{{localize "midgard5.defenseBonus-short"}}BGw
{{item.label}}{{actorItemValue ../actor._id itemId "lpProtection"}}{{actorItemValue ../actor._id itemId "apProtection"}}{{actorItemValue ../actor._id itemId "stats.attackBonus"}}{{actorItemValue ../actor._id itemId "stats.defenseBonus"}}{{actorItemValue ../actor._id itemId "stats.movementBonus"}}{{actorItemValue ../actor._id itemId "attributeMod.gw"}}
diff --git a/templates/sheets/character/main.hbs b/templates/sheets/character/main.hbs index ec50934..9ea39e6 100644 --- a/templates/sheets/character/main.hbs +++ b/templates/sheets/character/main.hbs @@ -26,5 +26,9 @@ {{> "systems/midgard5/templates/sheets/character/gear.hbs"}} +
+ {{> "systems/midgard5/templates/sheets/character/spells.hbs"}} +
+ \ No newline at end of file diff --git a/templates/sheets/character/skills.hbs b/templates/sheets/character/skills.hbs index 6fd2db8..98ba50e 100644 --- a/templates/sheets/character/skills.hbs +++ b/templates/sheets/character/skills.hbs @@ -18,14 +18,6 @@ {{/each}} - - - {{localize "midgard5.new-skill"}} - - - - - @@ -49,14 +41,29 @@ {{/each}} + + - - {{localize "midgard5.new-skill"}} - - - - + + + + + + + + + + + {{#each data.calc.skills.innate as |skill skillId|}} + + + + + + + + {{/each}}
{{localize "midgard5.innate-ability"}}{{localize "midgard5.fw"}}{{localize "midgard5.bonus"}}{{localize "midgard5.ew"}}
{{skill.label}}{{skill.fw}}{{skill.calc.bonus}}{{skill.calc.ew}}
@@ -64,7 +71,6 @@ {{localize "midgard5.weapon-skill"}} - {{localize "midgard5.special"}} {{localize "midgard5.fw"}} {{localize "midgard5.bonus"}} {{localize "midgard5.ew"}} @@ -75,28 +81,12 @@ {{#each data.calc.skills.combat as |skill skillId|}} {{skill.label}} - - {{#if (eq skillId ../data.skills.preferredCombatSkill)}} - - {{else}} - - {{/if}} - {{skill.fw}} {{skill.calc.bonus}} {{skill.calc.ew}} {{/each}} - - - {{localize "midgard5.new-skill"}} - - - - - - diff --git a/templates/sheets/character/spells.hbs b/templates/sheets/character/spells.hbs new file mode 100644 index 0000000..302e34a --- /dev/null +++ b/templates/sheets/character/spells.hbs @@ -0,0 +1,21 @@ + + + + + + + + + + {{#each data.calc.spells as |item itemId|}} + + + + + + {{/each}} + +
{{localize "ITEM.TypeSpell"}}{{localize "midgard5.ew"}}
+ {{item.label}} + {{localize item.process}} + {{item.calc.ew}}
diff --git a/templates/sheets/item/armor.hbs b/templates/sheets/item/armor.hbs new file mode 100644 index 0000000..6dc753a --- /dev/null +++ b/templates/sheets/item/armor.hbs @@ -0,0 +1,37 @@ +
+
+ +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
{{localize "midgard5.actor-lp"}}{{localize "midgard5.actor-ap"}}
{{localize "midgard5.attackBonus"}}{{localize "midgard5.defenseBonus"}}
{{localize "midgard5.movementRange"}}{{localize "midgard5.actor-gw-long"}}
+ + {{editor content=data.description target="data.description" button=true owner=owner editable=editable}} +
+
\ No newline at end of file diff --git a/templates/sheets/item/defensiveWeapon.hbs b/templates/sheets/item/defensiveWeapon.hbs new file mode 100644 index 0000000..7e9e4cd --- /dev/null +++ b/templates/sheets/item/defensiveWeapon.hbs @@ -0,0 +1,48 @@ +
+
+ +

+
+
+ + + + + + + + + + + + + +
+
+ + + + + + + + + +
+
{{localize "midgard5.defenseBonus"}}{{localize "midgard5.weapon-skill"}} + {{#if data.calc.combatSkills}} + + {{else}} + Assign item to character to select weapon skill + {{/if}} +
+ {{editor content=data.description target="data.description" button=true owner=owner editable=editable}} +
+
\ No newline at end of file diff --git a/templates/sheets/item/skill.hbs b/templates/sheets/item/skill.hbs index 7c980b1..879faf1 100644 --- a/templates/sheets/item/skill.hbs +++ b/templates/sheets/item/skill.hbs @@ -17,6 +17,7 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{localize "midgard5.bonus"}}{{localize "midgard5.actor-ap"}}
{{localize "midgard5.spell-castDuration"}}{{localize "midgard5.spell-range"}}
{{localize "midgard5.spell-effectTarget"}} + + {{localize "midgard5.spell-effectArea"}}
{{localize "midgard5.spell-effectDuration"}}{{localize "midgard5.spell-origin"}}
{{localize "midgard5.spell-type"}} + + {{localize "midgard5.spell-process"}} + +
+ {{editor content=data.description target="data.description" button=true owner=owner editable=editable}} +
+ \ No newline at end of file diff --git a/templates/sheets/item/weapon.hbs b/templates/sheets/item/weapon.hbs index e3b3e45..a5809ed 100644 --- a/templates/sheets/item/weapon.hbs +++ b/templates/sheets/item/weapon.hbs @@ -7,17 +7,23 @@ - - - diff --git a/tsconfig.json b/tsconfig.json index 2cae1d3..2d7c9b0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -65,15 +65,15 @@ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + //"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ /* Type Checking */ - "strict": true, /* Enable all strict type-checking options. */ - "noImplicitAny": false, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ - "strictNullChecks": false, /* When type checking, take into account `null` and `undefined`. */ + //"strict": true, /* Enable all strict type-checking options. */ + //"noImplicitAny": false, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ + //"strictNullChecks": false, /* When type checking, take into account `null` and `undefined`. */ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ + //"noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */
- - - - - - - - + +
+ + + + + + + + + + + + + + +