diff --git a/LICENSE b/LICENSE index 9a191a8..4d20996 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 Michael Stein +Copyright (c) 2022 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/foundryconfig.json b/foundryconfig.json index 54fa033..0b75816 100644 --- a/foundryconfig.json +++ b/foundryconfig.json @@ -1,5 +1,5 @@ { - "moduleName": "Midgard 5. Edition", - "repository": "https://github.com/michaelstein/foundry-vtt-system-midgard5", - "rawURL": "https://raw.githubusercontent.com/michaelstein/foundry-vtt-system-midgard5" -} \ No newline at end of file + "moduleName": "Midgard 5. Edition", + "repository": "https://github.com/Byroks/foundry-vtt-system-midgard5", + "rawURL": "https://raw.githubusercontent.com/Byroks/foundry-vtt-system-midgard5" +} diff --git a/lang/de.json b/lang/de.json index 9e7b2ea..d488c59 100644 --- a/lang/de.json +++ b/lang/de.json @@ -78,6 +78,7 @@ "midgard5.exp-available": "Erfahrungspunkte", "midgard5.grace": "Göttliche Gnade", "midgard5.destiny": "Schicksalsgunst", + "midgard5.luckPoints": "Glückspunkte", "midgard5.akrobatik": "Akrobatik", "midgard5.alchimie": "Alchimie", @@ -189,7 +190,7 @@ "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", @@ -202,7 +203,7 @@ "midgard5.spell-effectArea": "Wirkungsbereich", "midgard5.spell-effectDuration": "Wirkungsdauer", "midgard5.spell-origin": "Ursprung", - + "midgard5.mod-operation-add100": "Addieren (max 100)", "midgard5.mod-operation-add": "Addieren", "midgard5.mod-operation-set": "Basiswert", diff --git a/package.json b/package.json index 5bc2deb..d95d38a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "foundry-system-midgard5", - "version": "1.1.0", + "version": "1.2.0", "description": "", "main": "index.js", "scripts": { @@ -13,7 +13,7 @@ "build:watch:target": "gulp watchTarget", "clean": "gulp clean && gulp link --clean" }, - "author": "Michael Stein", + "author": "Simon Gustavs", "license": "MIT", "devDependencies": { "@babel/core": "^7.15.0", diff --git a/packs/macros/makros-kritische-ereignisse/kritische_fehler_beim_zaubern.json b/packs/macros/makros-kritische-ereignisse/kritische_fehler_beim_zaubern.json index c51048d..5375543 100644 --- a/packs/macros/makros-kritische-ereignisse/kritische_fehler_beim_zaubern.json +++ b/packs/macros/makros-kritische-ereignisse/kritische_fehler_beim_zaubern.json @@ -11,9 +11,9 @@ } }, "scope": "global", - "command": "main()\nasync function main() {\n\n//Das richtige Pack (Kompendium) holen\n\nconst pack = game.packs.get(\"midgard5.tabellen-kritische-ereignisse\");\n\nawait pack.getIndex();\n\n// Richtige Tabelle aus dem Pack holen\n\nlet entry = pack.index.find(e => e.name === \"Kritische Fehler beim Zaubern\");\n\n\n// Zum Schluss drauf würfeln\n\npack.getEntity(entry._id).then(table => table.draw());\n\n}", + "command": "await game.tables.getName(\"Kritische Fehler beim Zaubern\").draw()", "author": "CBq5YXAqbO7HoJ03", "img": "systems/midgard5/assets/icons/macro/kritfehlerzauber.svg", "actorIds": [], "_id": "XtzGuyYRyX8wVi1e" -} \ No newline at end of file +} diff --git a/packs/macros/makros-kritische-ereignisse/kritischer_erfolg_bei_der_abwehr.json b/packs/macros/makros-kritische-ereignisse/kritischer_erfolg_bei_der_abwehr.json index 4f890fc..d48183d 100644 --- a/packs/macros/makros-kritische-ereignisse/kritischer_erfolg_bei_der_abwehr.json +++ b/packs/macros/makros-kritische-ereignisse/kritischer_erfolg_bei_der_abwehr.json @@ -11,9 +11,9 @@ } }, "scope": "global", - "command": "main()\nasync function main() {\n\n//Das richtige Pack (Kompendium) holen\n\nconst pack = game.packs.get(\"midgard5.tabellen-kritische-ereignisse\");\n\nawait pack.getIndex();\n\n// Richtige Tabelle aus dem Pack holen\n\nlet entry = pack.index.find(e => e.name === \"Kritischer Erfolg bei der Abwehr\");\n\n// Zum Schluss drauf würfeln\n\npack.getEntity(entry._id).then(table => table.draw());\n\n}", + "command": "await game.tables.getName(\"Kritische Erfolg bei der Abwehr\").draw()", "author": "CBq5YXAqbO7HoJ03", "img": "systems/midgard5/assets/icons/macro/kriterfolgabwehr.svg", "actorIds": [], "_id": "qWyrwvh7g9CbTKg9" -} \ No newline at end of file +} diff --git a/packs/macros/makros-kritische-ereignisse/kritischer_fehler_bei_angriffen.json b/packs/macros/makros-kritische-ereignisse/kritischer_fehler_bei_angriffen.json index 9689a92..d79f3e1 100644 --- a/packs/macros/makros-kritische-ereignisse/kritischer_fehler_bei_angriffen.json +++ b/packs/macros/makros-kritische-ereignisse/kritischer_fehler_bei_angriffen.json @@ -11,9 +11,9 @@ } }, "scope": "global", - "command": "main()\nasync function main() {\n\n//Das richtige Pack (Kompendium) holen\n\nconst pack = game.packs.get(\"midgard5.tabellen-kritische-ereignisse\");\n\nawait pack.getIndex();\n\n// Richtige Tabelle aus dem Pack holen\n\nlet entry = pack.index.find(e => e.name === \"Kritischer Fehler bei Angriffen\");\n\n// Zum Schluss drauf würfeln\n\npack.getEntity(entry._id).then(table => table.draw());\n\n}", + "command": "await game.tables.getName(\"Kritische Fehler bei Angriffen\").draw()", "author": "CBq5YXAqbO7HoJ03", "img": "systems/midgard5/assets/icons/macro/kritfehlerangriff.svg", "actorIds": [], "_id": "798kmgnTkpfP89Z9" -} \ No newline at end of file +} diff --git a/packs/macros/makros-kritische-ereignisse/kritischer_fehler_bei_der_abwehr.json b/packs/macros/makros-kritische-ereignisse/kritischer_fehler_bei_der_abwehr.json index 83a0d86..a635cf0 100644 --- a/packs/macros/makros-kritische-ereignisse/kritischer_fehler_bei_der_abwehr.json +++ b/packs/macros/makros-kritische-ereignisse/kritischer_fehler_bei_der_abwehr.json @@ -11,9 +11,9 @@ } }, "scope": "global", - "command": "main()\nasync function main() {\n\n//Das richtige Pack (Kompendium) holen\n\nconst pack = game.packs.get(\"midgard5.tabellen-kritische-ereignisse\");\n\nawait pack.getIndex();\n\n// Richtige Tabelle aus dem Pack holen\n\nlet entry = pack.index.find(e => e.name === \"Kritischer Fehler bei der Abwehr\");\n\n// Zum Schluss drauf würfeln\n\npack.getEntity(entry._id).then(table => table.draw());\n\n}", + "command": "await game.tables.getName(\"Kritische Fehler bei der Abwehr\").draw()", "author": "CBq5YXAqbO7HoJ03", "img": "systems/midgard5/assets/icons/macro/kritfehlerabwehr.svg", "actorIds": [], "_id": "W7rYb00B6rtabV05" -} \ No newline at end of file +} diff --git a/packs/macros/makros-kritische-ereignisse/kritischer_schaden.json b/packs/macros/makros-kritische-ereignisse/kritischer_schaden.json index e869b52..001d6cd 100644 --- a/packs/macros/makros-kritische-ereignisse/kritischer_schaden.json +++ b/packs/macros/makros-kritische-ereignisse/kritischer_schaden.json @@ -11,9 +11,9 @@ } }, "scope": "global", - "command": "main()\nasync function main() {\n\n//Das richtige Pack (Kompendium) holen\n\nconst pack = game.packs.get(\"midgard5.tabellen-kritische-ereignisse\");\n\nawait pack.getIndex();\n\n// Richtige Tabelle aus dem Pack holen\n\nlet entry = pack.index.find(e => e.name === \"Kritischer Schaden\");\n\n// Zum Schluss drauf würfeln\n\npack.getEntity(entry._id).then(table => table.draw());\n\n}", + "command": "await game.tables.getName(\"Kritischer Schaden\").draw()", "author": "CBq5YXAqbO7HoJ03", "img": "systems/midgard5/assets/icons/macro/kriterfolgangriff.svg", "actorIds": [], "_id": "48DUqxdpHDCGKOHp" -} \ No newline at end of file +} diff --git a/source/module/actors/M5Character.ts b/source/module/actors/M5Character.ts index a07a6c6..5177c34 100644 --- a/source/module/actors/M5Character.ts +++ b/source/module/actors/M5Character.ts @@ -1,9 +1,8 @@ -import { M5Item } from "../items/M5Item" -import { M5Attribute, M5CharacterCalculatedData, M5ItemMod, M5ModOperation, M5ModResult, M5RollData, M5Skill, M5SkillCalculated, M5SkillLearned } from "../M5Base" -import M5ModAggregate from "./M5ModAggregate" +import { M5Item } from "../items/M5Item"; +import { M5Attribute, M5CharacterCalculatedData, M5ItemMod, M5ModOperation, M5ModResult, M5RollData, M5Skill, M5SkillCalculated, M5SkillLearned } from "../M5Base"; +import M5ModAggregate from "./M5ModAggregate"; export class M5Character extends Actor { - // constructor( // data: ConstructorParameters[0], // context?: ConstructorParameters[1] @@ -13,23 +12,19 @@ export class M5Character extends Actor { // } 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(attribute: M5Attribute) { - const value = this.attributeMinMax(attribute) - if (value > 95) - return 2 - if (value > 80) - return 1 - if (value > 20) - return 0 - if (value > 5) - return -1 - return -2 + const value = this.attributeMinMax(attribute); + if (value > 95) return 2; + if (value > 80) return 1; + if (value > 20) return 0; + if (value > 5) return -1; + return -2; } - derivedData(skip: { mods?: boolean, skills?: boolean, weapons?: boolean, defensiveWeapons?: boolean, armor?: boolean, items?: boolean, spells?: boolean } = {} ): M5CharacterCalculatedData { + derivedData(skip: { mods?: boolean; skills?: boolean; weapons?: boolean; defensiveWeapons?: boolean; armor?: boolean; items?: boolean; spells?: boolean } = {}): M5CharacterCalculatedData { let ret: M5CharacterCalculatedData = { level: 0, attributes: { @@ -41,7 +36,7 @@ export class M5Character extends Actor { zt: { value: 0, bonus: 0, mods: [] }, au: { value: 0, bonus: 0, mods: [] }, pa: { value: 0, bonus: 0, mods: [] }, - wk: { value: 0, bonus: 0, mods: [] } + wk: { value: 0, bonus: 0, mods: [] }, }, stats: { lp: { value: 0, mods: [] }, @@ -58,7 +53,7 @@ export class M5Character extends Actor { brawl: { value: 0, mods: [] }, brawlEw: 0, poisonResistance: { value: 0, mods: [] }, - enduranceBonus: 0 + enduranceBonus: 0, }, skillMods: {}, skills: { @@ -66,187 +61,200 @@ export class M5Character extends Actor { general: {}, combat: {}, language: {}, - custom: {} + custom: {}, }, gear: { weapons: {}, defensiveWeapons: {}, armor: {}, - items: {} + items: {}, }, - spells: {} - } as M5CharacterCalculatedData + spells: {}, + } as M5CharacterCalculatedData; - const context = (this as any) - if (!context) - return null + const context = this as any; + if (!context) return null; - const data = (this as any).system - if (!data) - return null - - ret.level = M5Character.levelFromExp(data.es) + const data = (this as any).system; + if (!data) return null; - 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) - ret.attributes.ko.value = M5Character.attributeMinMax(data.attributes.ko) - ret.attributes.in.value = M5Character.attributeMinMax(data.attributes.in) - ret.attributes.zt.value = M5Character.attributeMinMax(data.attributes.zt) - ret.attributes.au.value = M5Character.attributeMinMax(data.attributes.au) - ret.attributes.pa.value = M5Character.attributeMinMax(data.attributes.pa) - ret.attributes.wk.value = M5Character.attributeMinMax(data.attributes.wk) + ret.level = M5Character.levelFromExp(data.es); - ret.attributes.st.bonus = M5Character.attributeBonus(data.attributes.st) - ret.attributes.gs.bonus = M5Character.attributeBonus(data.attributes.gs) - ret.attributes.gw.bonus = M5Character.attributeBonus(data.attributes.gw) - ret.attributes.ko.bonus = M5Character.attributeBonus(data.attributes.ko) - ret.attributes.in.bonus = M5Character.attributeBonus(data.attributes.in) - ret.attributes.zt.bonus = M5Character.attributeBonus(data.attributes.zt) - ret.attributes.au.bonus = M5Character.attributeBonus(data.attributes.au) - ret.attributes.pa.bonus = M5Character.attributeBonus(data.attributes.pa) - ret.attributes.wk.bonus = M5Character.attributeBonus(data.attributes.wk) + 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); + ret.attributes.ko.value = M5Character.attributeMinMax(data.attributes.ko); + ret.attributes.in.value = M5Character.attributeMinMax(data.attributes.in); + ret.attributes.zt.value = M5Character.attributeMinMax(data.attributes.zt); + ret.attributes.au.value = M5Character.attributeMinMax(data.attributes.au); + ret.attributes.pa.value = M5Character.attributeMinMax(data.attributes.pa); + ret.attributes.wk.value = M5Character.attributeMinMax(data.attributes.wk); + + ret.attributes.st.bonus = M5Character.attributeBonus(data.attributes.st); + ret.attributes.gs.bonus = M5Character.attributeBonus(data.attributes.gs); + ret.attributes.gw.bonus = M5Character.attributeBonus(data.attributes.gw); + ret.attributes.ko.bonus = M5Character.attributeBonus(data.attributes.ko); + ret.attributes.in.bonus = M5Character.attributeBonus(data.attributes.in); + ret.attributes.zt.bonus = M5Character.attributeBonus(data.attributes.zt); + ret.attributes.au.bonus = M5Character.attributeBonus(data.attributes.au); + ret.attributes.pa.bonus = M5Character.attributeBonus(data.attributes.pa); + ret.attributes.wk.bonus = M5Character.attributeBonus(data.attributes.wk); + + 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.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) - if (!skip?.mods) { - const aggregate = new M5ModAggregate(data, ret) + const aggregate = new M5ModAggregate(data, ret); - context.items?.filter(item => item.type === "item").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() + context.items + ?.filter((item) => item.type === "item") + .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?.items) { - context.items?.filter(item => item.type === "item").forEach(item => { - item.prepareDerivedData() + if (!skip?.items) { + context.items + ?.filter((item) => item.type === "item") + .forEach((item) => { + item.prepareDerivedData(); - let label = item.name - if (item.system.magic) { - label += "*" - } + let label = item.name; + if (item.system.magic) { + label += "*"; + } - ret.gear.items[item.id] = { - label: label, - magic: item.system.magic, - calc: item.system.calc - } - }) + ret.gear.items[item.id] = { + label: label, + magic: item.system.magic, + calc: item.system.calc, + }; + }); } if (!skip?.skills) { - context.items?.filter(item => item.type === "skill").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 - }) + context.items + ?.filter((item) => item.type === "skill") + .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; + }); } - if (!skip?.weapons) { - context.items?.filter(item => item.type === "weapon").forEach(item => { - item.prepareDerivedData() + if (!skip?.weapons) { + context.items + ?.filter((item) => item.type === "weapon") + .forEach((item) => { + item.prepareDerivedData(); - let label = item.name - if (item.system.magic) { - label += "*(" - + (item.system.stats.attackBonus < 0 ? "" : "+") - + item.system.stats.attackBonus + "/" - + (item.system.stats.damageBonus < 0 ? "" : "+") - + item.system.stats.damageBonus + ")" - } + let label = item.name; + if (item.system.magic) { + label += + "*(" + + (item.system.stats.attackBonus < 0 ? "" : "+") + + item.system.stats.attackBonus + + "/" + + (item.system.stats.damageBonus < 0 ? "" : "+") + + item.system.stats.damageBonus + + ")"; + } - ret.gear.weapons[item.id] = { - label: label, - skillId: item.system.skillId, - magic: item.system.magic, - calc: item.system.calc - } - }) + ret.gear.weapons[item.id] = { + label: label, + skillId: item.system.skillId, + magic: item.system.magic, + calc: item.system.calc, + }; + }); } - if (!skip?.defensiveWeapons) { - context.items?.filter(item => item.type === "defensiveWeapon").forEach(item => { - item.prepareDerivedData() + if (!skip?.defensiveWeapons) { + context.items + ?.filter((item) => item.type === "defensiveWeapon") + .forEach((item) => { + item.prepareDerivedData(); - let label = item.name - if (item.system.magic) { - label += "*(" - + (item.system.stats.defenseBonus < 0 ? "" : "+") - + item.system.stats.defenseBonus + ")" - } + let label = item.name; + if (item.system.magic) { + label += "*(" + (item.system.stats.defenseBonus < 0 ? "" : "+") + item.system.stats.defenseBonus + ")"; + } - ret.gear.defensiveWeapons[item.id] = { - label: label, - skillId: item.system.skillId, - magic: item.system.magic, - calc: item.system.calc - } - }) + ret.gear.defensiveWeapons[item.id] = { + label: label, + skillId: item.system.skillId, + magic: item.system.magic, + calc: item.system.calc, + }; + }); } - if (!skip?.armor) { - context.items?.filter(item => item.type === "armor").forEach(item => { - item.prepareDerivedData() + if (!skip?.armor) { + context.items + ?.filter((item) => item.type === "armor") + .forEach((item) => { + item.prepareDerivedData(); - let label = item.name - if (item.system.magic) { - label += "*" - } + let label = item.name; + if (item.system.magic) { + label += "*"; + } - ret.gear.armor[item.id] = { - label: label, - magic: item.system.magic, - calc: item.system.calc - } - }) + ret.gear.armor[item.id] = { + label: label, + magic: item.system.magic, + calc: item.system.calc, + }; + }); } - if (!skip?.spells) { - context.items?.filter(item => item.type === "spell").forEach(item => { - item.prepareDerivedData() + if (!skip?.spells) { + context.items + ?.filter((item) => item.type === "spell") + .forEach((item) => { + item.prepareDerivedData(); - ret.spells[item.id] = { - label: item.name, - process: "midgard5.spell-process-" + item.system.process, - calc: item.system.calc - } - }) + ret.spells[item.id] = { + label: item.name, + process: "midgard5.spell-process-" + item.system.process, + calc: item.system.calc, + }; + }); } - return ret + return ret; } prepareDerivedData() { - console.log("M5Character", "prepareDerivedData") - const data = (this as any).system - data.calc = this.derivedData({}) + console.log("M5Character", "prepareDerivedData"); + const data = (this as any).system; + data.calc = this.derivedData({}); } override getRollData(): any { @@ -255,88 +263,93 @@ export class M5Character extends Actor { i: null, iType: null, rolls: {}, - res: {} - } as M5RollData + res: {}, + } as M5RollData; } - static readonly levelThreshold: Array = [0, 100, 250, 500, 750, 1000, 1250, 1500, 1750, 2000, 2500, 3000, 3500, 4000, 4500, 5000, 6000, 7000, 8000, 9000, 10000, 12500, 15000, 17500, 20000, 22500, 25000, 30000, 35000, 40000, 45000, 50000, 55000, 60000, 65000, 70000, 75000, 80000, 85000, 90000, 95000, 100000, 105000, 110000, 115000, 120000, 125000, 130000, 135000, 140000, 145000, 150000, 155000, 160000, 165000, 170000, 175000, 180000, 185000, 190000, 195000, 200000, 205000, 210000, 215000, 220000, 225000, 230000, 235000, 240000, 245000, 250000, 255000, 260000, 265000, 270000, 275000, 280000] + static readonly levelThreshold: Array = [ + 0, 100, 250, 500, 750, 1000, 1250, 1500, 1750, 2000, 2500, 3000, 3500, 4000, 4500, 5000, 6000, 7000, 8000, 9000, 10000, 12500, 15000, 17500, 20000, 22500, 25000, 30000, 35000, 40000, + 45000, 50000, 55000, 60000, 65000, 70000, 75000, 80000, 85000, 90000, 95000, 100000, 105000, 110000, 115000, 120000, 125000, 130000, 135000, 140000, 145000, 150000, 155000, 160000, + 165000, 170000, 175000, 180000, 185000, 190000, 195000, 200000, 205000, 210000, 215000, 220000, 225000, 230000, 235000, 240000, 245000, 250000, 255000, 260000, 265000, 270000, 275000, + 280000, + ]; static levelFromExp(exp: number): number { - const ret = M5Character.levelThreshold.findIndex(val => val > exp) - return ret === -1 ? M5Character.levelThreshold.length : ret + const ret = M5Character.levelThreshold.findIndex((val) => val > exp); + return ret === -1 ? M5Character.levelThreshold.length : ret; } static readonly defenseThreshold: Array<[number, number]> = [ - [1, 11], - [2, 12], - [5, 13], - [10, 14], - [15, 15], - [20, 16], + [30, 18], [25, 17], - [30, 18] - ] + [20, 16], + [15, 15], + [10, 14], + [5, 13], + [2, 12], + [1, 11], + ]; static defenseFromLevel(lvl: number): number { - const ret = M5Character.defenseThreshold.find(val => val[0] >= lvl) - return ret ? ret[1] : M5Character.defenseThreshold[M5Character.defenseThreshold.length - 1][1] + const ret = M5Character.defenseThreshold.find((val) => val[0] <= lvl); + return ret ? ret[1] : M5Character.defenseThreshold[M5Character.defenseThreshold.length - 1][1]; } static readonly spellCastingThreshold: Array<[number, number]> = [ - [1, 11], - [2, 12], - [4, 13], - [6, 14], - [8, 15], - [10, 16], + [20, 18], [15, 17], - [20, 18] - ] + [10, 16], + [8, 15], + [6, 14], + [4, 13], + [2, 12], + [1, 11], + ]; static spellCastingFromLevel(lvl: number): number { - const ret = M5Character.spellCastingThreshold.find(val => val[0] >= lvl) - return ret ? ret[1] : M5Character.spellCastingThreshold[M5Character.spellCastingThreshold.length - 1][1] + const ret = M5Character.spellCastingThreshold.find((val) => val[0] <= lvl); + return ret ? ret[1] : M5Character.spellCastingThreshold[M5Character.spellCastingThreshold.length - 1][1]; } skillBonus(skill: M5Skill, skillName?: string) { - const data = (this as any).system - return data.calc?.attributes[skill.attribute]?.bonus ?? 0 + const data = (this as any).system; + return data.calc?.attributes[skill.attribute]?.bonus ?? 0; } skillEw(skill: M5Skill, skillName?: string) { - const bonus = this.skillBonus(skill, skillName) - return skill.fw + bonus + const bonus = this.skillBonus(skill, skillName); + return skill.fw + bonus; } attribute(name: string): M5Attribute { - const data = (this as any).system - return data?.attributes[name] + const data = (this as any).system; + return data?.attributes[name]; } createSkill(skillName: string): Promise { const itemData = { name: skillName, - type: "skill" + type: "skill", }; - return (this as any).createEmbeddedDocuments("Item", [itemData]).then(docs => { - const item = docs[0] - return item - }) + 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) + if (!(this as any).items) return null; + return (this as any).getEmbeddedDocument("Item", itemId); } private modResult(value: number): M5ModResult { return { value: value, - mods: [{ - item: (game as Game).i18n.localize("ACTOR.TypeCharacter"), - operation: M5ModOperation.SET, - value: value - }] - } + mods: [ + { + item: (game as Game).i18n.localize("ACTOR.TypeCharacter"), + operation: M5ModOperation.SET, + value: value, + }, + ], + }; } - } diff --git a/source/module/items/M5Item.ts b/source/module/items/M5Item.ts index a3e30ae..550f6a8 100644 --- a/source/module/items/M5Item.ts +++ b/source/module/items/M5Item.ts @@ -1,39 +1,41 @@ -import { M5Character } from "../actors/M5Character" -import M5ModAggregate from "../actors/M5ModAggregate" -import { enumKeys, M5Attributes, M5ModOperation, M5ModPair, M5ModType, M5RollData, M5RollResult, M5Stats } from "../M5Base" -import { M5Roll } from "../rolls/M5Roll" +import { M5Character } from "../actors/M5Character"; +import M5ModAggregate from "../actors/M5ModAggregate"; +import { enumKeys, M5Attributes, M5ModOperation, M5ModPair, M5ModType, M5RollData, M5RollResult, M5Stats } from "../M5Base"; +import { M5Roll } from "../rolls/M5Roll"; export class M5Item extends Item { - static readonly SKILL = "skill" + static readonly SKILL = "skill"; prepareDerivedData() { - const itemId: string = (this as any).id - const itemType: string = (this as any).type - const actor = (this.actor as any) - const character = actor as M5Character - const itemData = (this as any).system - const calc = itemData.calc + const itemId: string = (this as any).id; + const itemType: string = (this as any).type; + const actor = this.actor as any; + const character = actor as M5Character; + const itemData = (this as any).system; + const calc = itemData.calc; if (itemType === "skill") { - calc.fw = itemData.fw - calc.bonus = 0 + calc.fw = itemData.fw; + calc.bonus = 0; - let pairs: Array = [{ - source: (this as any).name, - mod: { - type: M5ModType.SKILL, - id: itemId, - operation: M5ModOperation.SET, - value: itemData.fw - } - }] + let pairs: Array = [ + { + source: (this as any).name, + mod: { + type: M5ModType.SKILL, + id: itemId, + operation: M5ModOperation.SET, + value: itemData.fw, + }, + }, + ]; if (character) { - const actorCalc = character.derivedData({ skills: true, weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true }) + const actorCalc = character.derivedData({ skills: true, weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true }); if (actorCalc?.skillMods && Object.keys(actorCalc.skillMods).indexOf(itemId) !== -1) { - pairs = pairs.concat(actorCalc.skillMods[itemId]) + pairs = pairs.concat(actorCalc.skillMods[itemId]); } - + if (itemData?.attribute && itemData.attribute !== "") { pairs.push({ source: (this as any).name, @@ -41,171 +43,165 @@ export class M5Item extends Item { type: M5ModType.SKILL, id: itemId, operation: M5ModOperation.ADD, - value: actorCalc.attributes[itemData.attribute].bonus - } - }) + value: actorCalc.attributes[itemData.attribute].bonus, + }, + }); } } - 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 - }) + 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; + }); - calc.ew = calc.fw + calc.bonus - calc.sources = res.mods + calc.ew = calc.fw + calc.bonus; + calc.sources = res.mods; } else if (itemType === "weapon") { - calc.fw = 0 - calc.bonus = 0 - calc.special = itemData.special ? 2 : 0 - calc.ew = calc.special + itemData.stats.attackBonus - calc.combatSkills = null + calc.fw = 0; + calc.bonus = 0; + calc.special = itemData.special ? 2 : 0; + calc.ew = calc.special + itemData.stats.attackBonus; + calc.combatSkills = null; if (actor) { - const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true }) + const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true }); if (actorCalc) { - calc.ew += actorCalc.stats.attackBonus.value - calc.combatSkills = actorCalc.skills.combat + calc.ew += actorCalc.stats.attackBonus.value; + calc.combatSkills = actorCalc.skills.combat; } - const skill = character.getItem(itemData.skillId) + const skill = character.getItem(itemData.skillId); //console.log("M5Item.prepareDerivedData:weapon", itemData, skill?.system) if (skill) { - skill.prepareDerivedData() - const skillData = skill.system - calc.ew += skillData.calc.ew - calc.bonus += skillData.calc.bonus - calc.fw += skillData.fw + skill.prepareDerivedData(); + const skillData = skill.system; + calc.ew += skillData.calc.ew; + calc.bonus += skillData.calc.bonus; + calc.fw += skillData.fw; } } } else if (itemType === "defensiveWeapon") { - calc.fw = 0 - calc.bonus = 0 - calc.special = itemData.special ? 2 : 0 - calc.ew = calc.special + itemData.stats.defenseBonus - calc.combatSkills = null + calc.fw = 0; + calc.bonus = 0; + calc.special = itemData.special ? 2 : 0; + calc.ew = calc.special + itemData.stats.defenseBonus; + calc.combatSkills = null; if (actor) { - const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true }) + const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true }); if (actorCalc) { - calc.ew += actorCalc.stats.defense.value + actorCalc.stats.defenseBonus.value - calc.combatSkills = actorCalc.skills.combat + calc.ew += actorCalc.stats.defense.value + actorCalc.stats.defenseBonus.value; + calc.combatSkills = actorCalc.skills.combat; } - const skill = character.getItem(itemData.skillId) + const skill = character.getItem(itemData.skillId); //console.log("M5Item.prepareDerivedData:weapon", itemData, skill?.system) if (skill) { - skill.prepareDerivedData() - const skillData = skill.system - calc.ew += skillData.calc.ew - calc.bonus += skillData.calc.bonus - calc.fw += skillData.fw + skill.prepareDerivedData(); + const skillData = skill.system; + calc.ew += skillData.calc.ew; + calc.bonus += skillData.calc.bonus; + calc.fw += skillData.fw; } } } else if (itemType === "spell") { - calc.ew = itemData.bonus + calc.fw = 0; if (actor) { - const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true }) + const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true }); if (actorCalc) { - calc.ew += actorCalc.stats.spellCasting.value + calc.ew += actorCalc.stats.spellCasting.value; } } } else if (itemType === "item") { - calc.mods = {} - Object.keys(itemData?.mods).forEach(key => { - const mod = itemData.mods[key] - const modCalc = {} + calc.mods = {}; + Object.keys(itemData?.mods).forEach((key) => { + const mod = itemData.mods[key]; + const modCalc = {}; switch (mod.type) { case M5ModType.ATTRIBUTE: { for (const key of enumKeys(M5Attributes)) { - const val: string = M5Attributes[key] - modCalc[val] = (game as Game).i18n.localize(`midgard5.actor-${val}-long`) + const val: string = M5Attributes[key]; + modCalc[val] = (game as Game).i18n.localize(`midgard5.actor-${val}-long`); } - break + break; } case M5ModType.STAT: { for (const key of enumKeys(M5Stats)) { - const val: string = M5Stats[key] - modCalc[val] = (game as Game).i18n.localize(`midgard5.mod-stat-${val}`) + const val: string = M5Stats[key]; + modCalc[val] = (game as Game).i18n.localize(`midgard5.mod-stat-${val}`); } - break + break; } case M5ModType.SKILL: { if (character) { - const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true }) + const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true }); if (actorCalc) { - let category = (game as Game).i18n.localize("midgard5.skill") - Object.keys(actorCalc.skills.general).forEach(skillId => { - const skill = character.getItem(skillId) - if (skill) - modCalc[skillId] = `${category}: ${skill.name}` - }) - - category = (game as Game).i18n.localize("midgard5.language") - Object.keys(actorCalc.skills.language).forEach(skillId => { - const skill = character.getItem(skillId) - if (skill) - modCalc[skillId] = `${category}: ${skill.name}` - }) - - category = (game as Game).i18n.localize("midgard5.weapon-skill") - Object.keys(actorCalc.skills.combat).forEach(skillId => { - const skill = character.getItem(skillId) - if (skill) - modCalc[skillId] = `${category}: ${skill.name}` - }) - - category = (game as Game).i18n.localize("midgard5.innate-ability") - Object.keys(actorCalc.skills.innate).forEach(skillId => { - const skill = character.getItem(skillId) - if (skill) - modCalc[skillId] = `${category}: ${skill.name}` - }) + let category = (game as Game).i18n.localize("midgard5.skill"); + Object.keys(actorCalc.skills.general).forEach((skillId) => { + const skill = character.getItem(skillId); + if (skill) modCalc[skillId] = `${category}: ${skill.name}`; + }); + + category = (game as Game).i18n.localize("midgard5.language"); + Object.keys(actorCalc.skills.language).forEach((skillId) => { + const skill = character.getItem(skillId); + if (skill) modCalc[skillId] = `${category}: ${skill.name}`; + }); + + category = (game as Game).i18n.localize("midgard5.weapon-skill"); + Object.keys(actorCalc.skills.combat).forEach((skillId) => { + const skill = character.getItem(skillId); + if (skill) modCalc[skillId] = `${category}: ${skill.name}`; + }); + + category = (game as Game).i18n.localize("midgard5.innate-ability"); + Object.keys(actorCalc.skills.innate).forEach((skillId) => { + const skill = character.getItem(skillId); + if (skill) modCalc[skillId] = `${category}: ${skill.name}`; + }); } } - break + break; } } - calc.mods[key] = modCalc - }) + calc.mods[key] = modCalc; + }); } } getRollData() { - const actor = this.actor as any - const item = this as any + const actor = this.actor as any; + const item = this as any; let ret: M5RollData = actor?.getRollData() ?? { c: null, i: null, iType: null, rolls: {}, - res: {} - } + res: {}, + }; - ret.i = item.system - ret.iType = item.type - return ret + ret.i = item.system; + ret.iType = item.type; + return ret; } async roll() { - const item = (this as any) + const item = this as any; // Initialize chat data. - const speaker = ChatMessage.getSpeaker({ actor: this.actor }) - const rollMode = (game as Game).settings.get('core', 'rollMode') - const label = `[${item.type}] ${item.name}` + const speaker = ChatMessage.getSpeaker({ actor: this.actor }); + const rollMode = (game as Game).settings.get("core", "rollMode"); + const label = `[${item.type}] ${item.name}`; // If there's no roll data, send a chat message. - const formulaNames = item.system.rolls?.formulas ? Object.keys(item.system.rolls.formulas) : [] + const formulaNames = item.system.rolls?.formulas ? Object.keys(item.system.rolls.formulas) : []; if (formulaNames.length > 0) { - const rollData = this.getRollData() - formulaNames.forEach(formulaName => { - const formula = item.system.rolls.formulas[formulaName] + const rollData = this.getRollData(); + formulaNames.forEach((formulaName) => { + const formula = item.system.rolls.formulas[formulaName]; if (formula) { rollData.rolls[formulaName] = { formula: formula.formula, @@ -214,26 +210,26 @@ export class M5Item extends Item { result: "", total: 0, totalStr: "", - dice: {} - } as M5RollResult + dice: {}, + } as M5RollResult; } - }) - - const roll = new M5Roll(rollData, this.actor, item.name) - return roll.toMessage() + }); + + const roll = new M5Roll(rollData, this.actor, item.name); + return roll.toMessage(); } else { ChatMessage.create({ speaker: speaker, rollMode: rollMode, flavor: label, - content: item.system.description ?? '' - }) - return null + content: item.system.description ?? "", + }); + return null; } } getItem(itemId: string): any { - return (this as any).getEmbeddedDocument("Item", itemId) + return (this as any).getEmbeddedDocument("Item", itemId); } // migrateSystemData(): any { @@ -248,5 +244,4 @@ export class M5Item extends Item { // return super.migrateSystemData() // } - } diff --git a/source/module/sheets/M5CharacterSheet.ts b/source/module/sheets/M5CharacterSheet.ts index 54886aa..45454f8 100644 --- a/source/module/sheets/M5CharacterSheet.ts +++ b/source/module/sheets/M5CharacterSheet.ts @@ -1,19 +1,18 @@ -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" +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: 800, 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() { @@ -21,155 +20,152 @@ export default class M5CharacterSheet extends ActorSheet { // }Options extends ActorSheet.Options = ActorSheet.Options, Data extends object = ActorSheet.Data override getData(options?: Partial): ActorSheet.Data | Promise> { - const actor = this.actor as M5Character + const actor = this.actor as M5Character; //console.log("Sheet getData", (actor as any).data) - return Promise.resolve(super.getData(options)).then(context => { - actor.prepareDerivedData() + return Promise.resolve(super.getData(options)).then((context) => { + actor.prepareDerivedData(); + + context.actor = (actor as any).toObject(false); + context.data = (actor as any).system; - context.actor = (actor as any).toObject(false) - context.data = (actor as any).system - //console.log("Sheet Promise", context.actor, context.data) - return context - }) + return context; + }); } override setPosition(options = {}) { - const position = super.setPosition(options) - const fillerWidth = this.element.find(".attributes .filler:first").width() - this.element.find(".attributes .attribute-filler-fixed").width(fillerWidth) + const position = super.setPosition(options); + const fillerWidth = this.element.find(".attributes .filler:first").width(); + this.element.find(".attributes .attribute-filler-fixed").width(fillerWidth); return position; } override activateListeners(html: JQuery) { - super.activateListeners(html) + super.activateListeners(html); html.find(".update-lp").on("click", async (event) => { - const valueStr = event.target.dataset["value"] - const value = parseInt(valueStr) + const valueStr = event.target.dataset["value"]; + const value = parseInt(valueStr); this.actor.update({ data: { lp: { - value: value + 1 - } - } - }) - }) + value: value + 1, + }, + }, + }); + }); html.find(".update-ap").on("click", async (event) => { - const valueStr = event.target.dataset["value"] - const value = parseInt(valueStr) + const valueStr = event.target.dataset["value"]; + const value = parseInt(valueStr); this.actor.update({ data: { ap: { - value: value + 1 - } - } - }) - }) + value: value + 1, + }, + }, + }); + }); html.find(".roll-attribute-button").on("click", async (event) => { - let elem = event.target - let attributeStr = elem.dataset["attribute"] + let elem = event.target; + let attributeStr = elem.dataset["attribute"]; while (!attributeStr) { - elem = elem.parentElement - if (!elem) - return - attributeStr = elem.dataset["attribute"] + elem = elem.parentElement; + if (!elem) return; + attributeStr = elem.dataset["attribute"]; } - const attributeValue = parseInt(elem.dataset["value"]) + const attributeValue = parseInt(elem.dataset["value"]); - const roll = M5Roll.fromAttributeValue(this.actor, attributeStr, attributeValue) + const roll = M5Roll.fromAttributeValue(this.actor, attributeStr, attributeValue); //console.log("roll-attribute-button", parent, attributeStr, attributeValue, roll) - await roll.toMessage() - }) + await roll.toMessage(); + }); html.find(".edit-item").on("click", async (event) => { - let row = event.target.parentElement - let itemId = row.dataset["item"] + let row = event.target.parentElement; + let itemId = row.dataset["item"]; while (!itemId) { - row = row.parentElement - if (!row) - return - itemId = row.dataset["item"] + row = row.parentElement; + if (!row) return; + itemId = row.dataset["item"]; } - const context = this.actor as any - const item = context.items.get(itemId) - console.log("edit-item", item) - item.sheet.render(true) - }) + const context = this.actor as any; + const item = context.items.get(itemId); + console.log("edit-item", item); + item.sheet.render(true); + }); html.find(".item-delete").on("click", async (event) => { - let row = event.target.parentElement - let itemId = row.dataset["item"] + let row = event.target.parentElement; + let itemId = row.dataset["item"]; while (!itemId) { - row = row.parentElement - if (!row) - return - itemId = row.dataset["item"] + row = row.parentElement; + if (!row) return; + itemId = row.dataset["item"]; } - const context = this.actor as any - const item = context.items.get(itemId) - item.delete() - this.render(false) - }) + const context = this.actor as any; + const item = context.items.get(itemId); + item.delete(); + this.render(false); + }); html.find(".roll-learned-button").on("click", async (event) => { - const row = event.target.parentElement.parentElement - let skillId = row.dataset["item"] + const row = event.target.parentElement.parentElement; + let skillId = row.dataset["item"]; - const actor = this.actor as any - const item = actor.items.get(skillId) as M5Item - await item.roll() - }) + const actor = this.actor as any; + const item = actor.items.get(skillId) as M5Item; + await item.roll(); + }); html.find(".roll-general-button").on("click", async (event) => { - const row = event.target.parentElement.parentElement - let skillName = row.dataset["skill"] + const row = event.target.parentElement.parentElement; + let skillName = row.dataset["skill"]; - const data = this.actor.system - const unlearnedSkill = data.skills.general[skillName] as M5SkillUnlearned + const data = this.actor.system; + const unlearnedSkill = data.skills.general[skillName] as M5SkillUnlearned; - const roll = M5Roll.fromUnlearnedSkill(this.actor, unlearnedSkill, skillName) - await roll.toMessage() - }) + const roll = M5Roll.fromUnlearnedSkill(this.actor, unlearnedSkill, skillName); + await roll.toMessage(); + }); html.find(".learn-button").on("click", async (event) => { - const row = event.target.parentElement.parentElement - let skillName = row.dataset["skill"] + const row = event.target.parentElement.parentElement; + let skillName = row.dataset["skill"]; - const data = this.actor.system - const unlearnedSkill = data.skills.general[skillName] as M5SkillUnlearned + const data = this.actor.system; + const unlearnedSkill = data.skills.general[skillName] as M5SkillUnlearned; - const character = this.actor as M5Character - character.createSkill((game as Game).i18n.localize("midgard5." + skillName)).then(skill => { - const item = skill as any + const character = this.actor as M5Character; + character.createSkill((game as Game).i18n.localize("midgard5." + skillName)).then((skill) => { + const item = skill as any; item.update({ data: { fw: unlearnedSkill.initial, attribute: unlearnedSkill.attribute, skill: skillName, - type: "general" - } - }) - }) - }) + type: "general", + }, + }); + }); + }); html.find(".roll-weapon-button").on("click", async (event) => { - const row = event.target.parentElement.parentElement - let itemId = row.dataset["item"] + const row = event.target.parentElement.parentElement; + let itemId = row.dataset["item"]; - const context = this.actor as any - const item = context.items.get(itemId) as M5Item - await item.roll() - }) + const context = this.actor as any; + const item = context.items.get(itemId) as M5Item; + await item.roll(); + }); html.find(".roll-brawl-button").on("click", async (event) => { - const roll = M5Roll.brawl(this.actor) - await roll.toMessage() - }) + const roll = M5Roll.brawl(this.actor); + await roll.toMessage(); + }); // Drag & Drop const dragDrop = new DragDrop({ @@ -177,8 +173,8 @@ export default class M5CharacterSheet extends ActorSheet { 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) }, - }) - dragDrop.bind(html[0]) + }); + dragDrop.bind(html[0]); } _canDragStart(selector) { @@ -190,9 +186,9 @@ export default class M5CharacterSheet extends ActorSheet { } _onTransferItemDragStart(event) { - const li = event.currentTarget - $(event.currentTarget).attr("data-item-actorid", this.actor.id) - const item = this.actor.items.get(li.dataset.itemId) + const li = event.currentTarget; + $(event.currentTarget).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)) { @@ -200,45 +196,40 @@ export default class M5CharacterSheet extends ActorSheet { type: "Transfer", actorId: this.actor.id, data: item.toObject(false), - tokenId: null - } + tokenId: null, + }; - if (this.actor.isToken) - dragData.tokenId = this.actor.token.id + if (this.actor.isToken) dragData.tokenId = this.actor.token.id; - event.dataTransfer.setData("text/plain", JSON.stringify(dragData)) + event.dataTransfer.setData("text/plain", JSON.stringify(dragData)); } else { - return false + return false; } } async _onTransferItemDrop(event) { // Try to extract the data - let data = null + let data = null; try { - data = JSON.parse(event.dataTransfer.getData("text/plain")) - if (data.type !== "Transfer") - return false + data = JSON.parse(event.dataTransfer.getData("text/plain")); + if (data.type !== "Transfer") return false; } catch (err) { - return false + return false; } - if (!data.data) - return false + if (!data.data) return false; - if (data.actorId === this.actor.id) - return false + if (data.actorId === this.actor.id) return false; try { - this.actor.createEmbeddedDocuments("Item", [duplicate(data.data)]) // Create a new Item - const actor = (game as any).actors.get(data.actorId) - await actor.items.get(data.data._id)?.delete() // Delete originating item from other actor + this.actor.createEmbeddedDocuments("Item", [duplicate(data.data)]); // Create a new Item + const actor = (game as any).actors.get(data.actorId); + await actor.items.get(data.data._id)?.delete(); // Delete originating item from other actor } catch (e) { - console.error("Error transfering item between actors", e) - return false + console.error("Error transfering item between actors", e); + return false; } - return true + return true; } - } diff --git a/source/system.json b/source/system.json index 87e749d..2e14ac6 100644 --- a/source/system.json +++ b/source/system.json @@ -1,75 +1,73 @@ { - "id": "midgard5", - "title": "Midgard 5. Edition", - "description": "The German RPG Midgard 5. Edition", - "version": "1.1.0", - "compatibility": { - "minimum": "10", - "verified": "10" + "id": "midgard5", + "title": "Midgard 5. Edition", + "description": "The German RPG Midgard 5. Edition", + "version": "1.2.0", + "compatibility": { + "minimum": "10", + "verified": "10" + }, + "authors": [{ "name": "Byroks" }], + "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" }, - "authors": [ - { "name": "Michael Stein" } - ], - "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", - "name": "Deutsch", - "path": "lang/de.json" - } - ], - "gridDistance": 1, - "gridUnits": "m", - "primaryTokenAttribute": "lp", - "secondaryTokenAttribute": "ap", - "url": "https://github.com/michaelstein/foundry-vtt-system-midgard5", - "manifest": "https://github.com/michaelstein/foundry-vtt-system-midgard5/releases/download/v1.1.0/system.json", - "download": "https://github.com/michaelstein/foundry-vtt-system-midgard5/releases/download/v1.1.0/midgard5-v1.1.0.zip", - "initiative": "@calc.attributes.gw.value", - "license": "LICENSE.txt" + { + "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", + "name": "Deutsch", + "path": "lang/de.json" + } + ], + "gridDistance": 1, + "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", + "license": "LICENSE.txt" } diff --git a/templates/sheets/character/base_values.hbs b/templates/sheets/character/base_values.hbs index b159492..ddcfcf3 100644 --- a/templates/sheets/character/base_values.hbs +++ b/templates/sheets/character/base_values.hbs @@ -52,6 +52,10 @@ {{localize "midgard5.exp-available"}} + + {{localize "midgard5.luckPoints"}} + + diff --git a/tsconfig.json b/tsconfig.json index 2d7c9b0..983632f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,29 +9,23 @@ // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ /* Language and Environment */ - "target": "ES2017", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ - "lib": [ - "DOM", - "ES6", - "ES2017" - ], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + "target": "ES2017" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, + "lib": ["DOM", "ES6", "ES2017"] /* Specify a set of bundled library declaration files that describe the target runtime environment. */, // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ /* Modules */ - "module": "commonjs", /* Specify what module code is generated. */ - "rootDir": "./source", /* Specify the root folder within your source files. */ - "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + "module": "commonjs" /* Specify what module code is generated. */, + "rootDir": "./source" /* Specify the root folder within your source files. */, + "moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */, // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ - "types": [ - "@league-of-foundry-developers/foundry-vtt-types" - ], /* Specify type package names to be included without being referenced in a source file. */ + "types": ["@league-of-foundry-developers/foundry-vtt-types"] /* Specify type package names to be included without being referenced in a source file. */, // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - "resolveJsonModule": true, /* Enable importing .json files */ + "resolveJsonModule": true /* Enable importing .json files */, // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ /* JavaScript Support */ // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ @@ -45,7 +39,7 @@ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ // "outDir": "./", /* Specify an output folder for all emitted files. */ // "removeComments": true, /* Disable emitting comments. */ - "noEmit": true, /* Disable emitting files from a compilation. */ + "noEmit": true /* Disable emitting files from a compilation. */, // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ @@ -63,7 +57,7 @@ /* Interop Constraints */ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ // "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. */ + "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. */ /* Type Checking */ @@ -93,7 +87,5 @@ //"include": [ // "./Source/**/*.ts" //] - "exclude": [ - "gulpfile.ts" - ] -} \ No newline at end of file + "exclude": ["gulpfile.ts"] +}