diff --git a/lang/en.json b/lang/en.json index 443a221..70d1616 100644 --- a/lang/en.json +++ b/lang/en.json @@ -23,6 +23,7 @@ "CURRENCY.QUARTER": "Quarter", "CURRENCY.SHEKEL": "Shekel", "CURRENCY.TITLE": "Currency", + "CURRENCY.SILVER": "Silver", "DICE.ROLL": "Dice roll", @@ -62,6 +63,14 @@ "ROLL.SUCCESS": "Success", "ROLL.FAILURE": "Failure", + "ROLL.TITLE": "Roll dice", + "BUTTON.ROLL": "Roll", + "BUTTON.CANCEL": "Cancel", + "ROLL.CLOSED": "Closed", + "ROLL.OPENED": "Opened", + "MENU.SHOWROLLDIALOG": "Show diceroller dialog", + "ROLL.OPENCLOSE": "Open / Close", + "ROLL.EXCEPTIONAL": "Exceptional", "SKILL.TYPE": "Type", "SKILL.BASE": "Basic", @@ -73,6 +82,9 @@ "SPELL.DIFFICULTY": "Difficulty", "SPELL.ROLL": "Roll", "SPELL.COST": "Cost", + "SPELL.ATTACKROLL": "Attack roll", + "SPELL.OPPOSITE": "Opposite", + "SPELL.RITUAL": "Ritual", "STATS.HEALTH": "Health", "STATS.MANA": "Mana", diff --git a/lang/sv.json b/lang/sv.json index fd20903..04ec44e 100644 --- a/lang/sv.json +++ b/lang/sv.json @@ -24,6 +24,7 @@ "CURRENCY.QUARTER": "Kvarting", "CURRENCY.SHEKEL": "Shekel", "CURRENCY.TITLE": "Mynt", + "CURRENCY.SILVER": "Silver", "DICE.ROLL": "Tärningsslag", @@ -64,6 +65,15 @@ "ROLL.SUCCESS": "Lyckat", "ROLL.FAILURE": "Misslyckat", + "ROLL.TITLE": "Slå tärningar", + "BUTTON.ROLL": "Slå", + "BUTTON.CANCEL": "Avbryt", + "ROLL.CLOSED": "Stängd", + "ROLL.OPENED": "Öppnad", + "MENU.SHOWROLLDIALOG": "Visa tärningsdialog", + "ROLL.OPENCLOSE": "Öppna / Stäng", + "ROLL.EXCEPTIONAL": "Exceptionellt", + "SKILL.TYPE": "Typ", "SKILL.BASE": "Grundfärdigheter", "SKILL.ADVENTURE": "Äventyrsfärdigheter", @@ -72,8 +82,12 @@ "SKILL.LANGUAGE": "Språk", "SPELL.DIFFICULTY": "Svårighet", - "SPELL.ROLL": "Slag", + "SPELL.ROLLTITLE": "Slag", "SPELL.COST": "Kostnad", + "SPELL.ROLL": "Färdighetsslag", + "SPELL.ATTACKROLL": "Anfallsslag", + "SPELL.OPPOSITE": "Motsatt", + "SPELL.RITUAL": "Ritual", "STATS.HEALTH": "Hälsa", "STATS.MANA": "Skuld", diff --git a/module/actors/actor-sheet.js b/module/actors/actor-sheet.js index 2d94178..74b2937 100644 --- a/module/actors/actor-sheet.js +++ b/module/actors/actor-sheet.js @@ -139,6 +139,186 @@ export class ActorSheetKH extends ActorSheet { }, ]); + new ContextMenu(html, "li.item-weapon", [ + { + name: game.i18n.localize("MENU.SHOWROLLDIALOG"), + icon: '', + callback: (li) => { + let itemId = li.data("itemId"); + let _item = this.actor.items.find((element) => element._id == itemId); + + // Retrieve skill based on name + let skill = this.actor.items.find((element) => element.name === _item.data.data.skill.value); + + let skillName = skill.name + let skillValue = skill.data.data.value + let showValue = false + + if(this.actor.data.type === "character") { + showValue = true + } + + this.khRoller.rollSkillDialogInChat(skillName, skillValue, showValue, this.actor) + }, + }, + { + name: game.i18n.localize("MENU.SENTTOCHAT"), + icon: '', + callback: (li) => { + let itemId = li.data("itemId"); + this._itemDetailsToChat(itemId); + }, + }, + ]); + + new ContextMenu(html, "li.item-skill", [ + { + name: game.i18n.localize("MENU.SHOWROLLDIALOG"), + icon: '', + callback: (li) => { + let itemId = li.data("itemId"); + let _item = this.actor.items.find((element) => element._id == itemId); + + let skillName = _item.name + let skillValue = _item.data.data.value + let showValue = false + + if(this.actor.data.type === "character") { + showValue = true + } + + this.khRoller.rollSkillDialogInChat(skillName, skillValue, showValue, this.actor) + }, + }, + { + name: game.i18n.localize("MENU.SENTTOCHAT"), + icon: '', + callback: (li) => { + let itemId = li.data("itemId"); + this._itemDetailsToChat(itemId); + }, + }, + ]); + + new ContextMenu(html, "li.item-spell", [ + { + name: game.i18n.localize("MENU.SHOWROLLDIALOG"), + icon: '', + callback: (li) => { + let itemId = li.data("itemId"); + let _item = this.actor.items.find((element) => element._id == itemId); + + if (!_item) { + _item = game.items.get(itemId); + + if (!_item) { + console.log("IMPORT ERROR") + return + } + } + + let showValue = false + let difficulty = 0 + + if(this.actor.data.type === "character") { + showValue = true + } + + switch (_item.data.data.difficulty.value) { + case "simple": + difficulty = 5 + break; + case "easy": + difficulty = 2 + break; + case "hard": + difficulty = -2 + break; + case "daunting": + difficulty = -5 + break; + } + + if(_item.data.data.roll.value === "roll" || _item.data.data.roll.value === "attackroll") { + // Retrieve skill based on name + let skill = this.actor.items.find((element) => element.name === _item.data.data.roll.skill); + + let skillName = _item.name + let skillValue = skill.data.data.value + + if(this.actor.data.type === "character") { + skillName = _item.name + " (" + skill.name + ")" + } + + this.khRoller.rollSkillDialogInChat(skillName, skillValue, showValue, this.actor, difficulty) + } else if(_item.data.data.roll.value === "opposite") { + // Retrieve skill based on name + let skill = this.actor.items.find((element) => element.name === _item.data.data.roll.skill); + + let skillName = _item.name + let skillValue = skill.data.data.value + + if(this.actor.data.type === "character") { + skillName = _item.name + " (" + skill.name + ")" + } + + this.khRoller.rollSkillDialogInChat(skillName, skillValue, showValue, this.actor, difficulty) + } else if(_item.data.data.roll.value === "ritual") { + console.log("Not supported yet") + this.khRoller.rollSkillDialogInChat("Ritual", -1, showValue, this.actor, difficulty) + } + }, + }, + { + name: game.i18n.localize("MENU.SENTTOCHAT"), + icon: '', + callback: (li) => { + let itemId = li.data("itemId"); + this._itemDetailsToChat(itemId); + }, + }, + ]); + + new ContextMenu(html, "li.item-attack", [ + { + name: game.i18n.localize("MENU.SHOWROLLDIALOG"), + icon: '', + callback: (li) => { + let skillValue = li.data("ability"); + let skillName = "ITEM.ATTACK"; + let showValue = false + + if(this.actor.data.type === "character") { + showValue = true + } + + this.khRoller.rollSkillDialogInChat(skillName, skillValue, showValue, this.actor) + }, + }, + { + name: game.i18n.localize("MENU.SENTTOCHAT"), + icon: '', + callback: (li) => { + let itemId = li.data("itemId"); + this._itemDetailsToChat(itemId); + }, + }, + ]); + + new ContextMenu(html, "li.item-defence", [ + { + name: game.i18n.localize("MENU.SHOWROLLDIALOG"), + icon: '', + callback: (li) => { + const skillValue = li.data("defence"); + + let skillName = "ADVERSARY.DEFENCE"; + + this.khRoller.rollSkillDialogInChat(skillName, skillValue, false, this.actor) + }, + } + ]); + html.find(".feature").click(async (ev) => { const featureName = $(ev.currentTarget).data("feature"); const featureValue = this.actor.data.data.feature[featureName].value; @@ -156,7 +336,35 @@ export class ActorSheetKH extends ActorSheet { // Delete Inventory Item html.find(".item-delete").click((ev) => { - const li = $(ev.currentTarget).parents(".item"); + let parent = $(ev.currentTarget).data("parent") + const li = $(ev.currentTarget).parents(parent); + const item = this.actor.getOwnedItem(li.data("itemId")); + + if(item) { + if (item.type === "armor") { + let initValue = -1 + + if (item.data.data.equipable.equipped) { + initValue = 4 + + this.actor.items.map((i) => { + if (i.type === "armor") { + if (i._id !== item._id && i.data.data.equipable.equipped && i.data?.data?.modifications) { + for (let k of Object.keys(i.data.data.modifications)) { + if (i.data.data.modifications[k].modtype === "init") { + initValue = i.data.data.modifications[k].value; + } + } + } + } + }); + } + + if (initValue > 0) { + this.actor.update({["data.combat.init"]: initValue}); + } + } + } this.actor.deleteOwnedItem(li.data("itemId")); @@ -165,7 +373,8 @@ export class ActorSheetKH extends ActorSheet { // Edit Inventory Item html.find(".item-edit").click(async (ev) => { - const li = $(ev.currentTarget).parents(".item"); + let parent = $(ev.currentTarget).data("parent") + let li = $(ev.currentTarget).parents(parent); let itemId = li.data("itemId"); let item = this.actor.getOwnedItem(itemId); @@ -184,7 +393,7 @@ export class ActorSheetKH extends ActorSheet { /* Roll spell cost */ html.find(".roll-spell-cost").click((ev) => { - const li = $(ev.currentTarget).parents(".item"); + const li = $(ev.currentTarget).parents(".item-spell"); let itemId = li.data("itemId"); let spell = this.actor.getOwnedItem(itemId); @@ -207,9 +416,74 @@ export class ActorSheetKH extends ActorSheet { } }); + html.find(".roll-spell-skill").click((ev) => { + const li = $(ev.currentTarget).parents(".item-spell"); + let itemId = li.data("itemId"); + let spell = this.actor.getOwnedItem(itemId); + + if (!spell) { + spell = game.items.get(itemId); + + if (!spell) { + console.log("IMPORT ERROR") + return + } + } + + let showValue = false + let difficulty = 0 + + if(this.actor.data.type === "character") { + showValue = true + } + + switch (spell.data.data.difficulty.value) { + case "simple": + difficulty = 5 + break; + case "easy": + difficulty = 2 + break; + case "hard": + difficulty = -2 + break; + case "daunting": + difficulty = -5 + break; + } + + if(spell.data.data.roll.value === "roll" || spell.data.data.roll.value === "attackroll") { + // Retrieve skill based on name + let skill = this.actor.items.find((element) => element.name === spell.data.data.roll.skill); + + let skillName = spell.name + let skillValue = skill.data.data.value + + if(this.actor.data.type === "character") { + skillName = spell.name + " (" + skill.name + ")" + } + + this.khRoller.rollSkillInChat(skillName, skillValue, showValue, this.actor, difficulty) + } else if(spell.data.data.roll.value === "opposite") { + // Retrieve skill based on name + let skill = this.actor.items.find((element) => element.name === spell.data.data.roll.skill); + + let skillName = spell.name + let skillValue = skill.data.data.value + + if(this.actor.data.type === "character") { + skillName = spell.name + " (" + skill.name + ")" + } + + this.khRoller.rollSkillInChat(skillName, skillValue, showValue, this.actor, difficulty) + } else if(spell.data.data.roll.value === "ritual") { + console.log("Not supported yet") + } + }); + /* Roll skill */ html.find(".roll-skill").click((ev) => { - const li = $(ev.currentTarget).parents(".item"); + const li = $(ev.currentTarget).parents(".item-skill"); let itemId = li.data("itemId"); let _item = this.actor.items.find((element) => element._id == itemId); @@ -226,7 +500,7 @@ export class ActorSheetKH extends ActorSheet { /* Roll weapon skill */ html.find(".roll-weapon-skill").click((ev) => { - const li = $(ev.currentTarget).parents(".item"); + const li = $(ev.currentTarget).parents(".item-weapon"); let itemId = li.data("itemId"); let weapon = this.actor.getOwnedItem(itemId); @@ -255,7 +529,7 @@ export class ActorSheetKH extends ActorSheet { /* Roll weapon damage */ html.find(".roll-damage").click((ev) => { - const li = $(ev.currentTarget).parents(".item"); + const li = $(ev.currentTarget).parents(".item-weapon"); let itemId = li.data("itemId"); let weapon = this.actor.getOwnedItem(itemId); @@ -318,6 +592,7 @@ export class ActorSheetKH extends ActorSheet { /* Toggle item equipped */ html.find(".items .item a.toggle-equipped").click(this._toggleEquippedItem.bind(this)); + html.find(".items .item-weapon a.toggle-equipped").click(this._toggleEquippedItem.bind(this)); /* Handle increase of items in inventory */ html.find(".item-quantity .quantity.increase").click(this._increaseQuantity.bind((this))); @@ -331,7 +606,7 @@ export class ActorSheetKH extends ActorSheet { /* Adversary specific */ html.find(".roll-adversary-attack").click((ev) => { - const li = $(ev.currentTarget).parents(".item"); + const li = $(ev.currentTarget).parents(".item-attack"); let skillValue = li.data("ability"); let skillName = "ITEM.ATTACK"; @@ -339,6 +614,30 @@ export class ActorSheetKH extends ActorSheet { this.khRoller.rollSkillInChat(skillName, skillValue, false, this.actor) }); + html.find(".roll-attack-damage").click((ev) => { + const li = $(ev.currentTarget).parents(".item-attack"); + let itemId = li.data("itemId"); + let weapon = this.actor.getOwnedItem(itemId); + + if (!weapon) { + weapon = game.items.get(itemId); + + if (!weapon) { + console.log("IMPORT ERROR") + return + } + } + + let damage = weapon.data.data.damage.value; + + let regex = /([0-9]*)t([0-9]*)/g; + let regexMatch; + + while (regexMatch = regex.exec(damage.toLowerCase())) { + this.khRoller.rollDamageInChat(regexMatch[1], this.actor) + } + }); + html.find(".roll-defence").click((ev) => { const skillValue = $(ev.currentTarget).data("defence"); @@ -480,7 +779,7 @@ export class ActorSheetKH extends ActorSheet { const item = this.actor.getOwnedItem(li.data("itemId")); const actor = this.actor; - if (item) { + if(item) { if(item.type === "armor") { let initValue = -1 diff --git a/module/actors/actor.js b/module/actors/actor.js index e7433b2..d082d58 100644 --- a/module/actors/actor.js +++ b/module/actors/actor.js @@ -12,7 +12,5 @@ export class ActorKH extends Actor { const data = actorData.data; const flags = actorData.flags; data.type = actorData.type; - - console.log("ACTOR DATA") } } \ No newline at end of file diff --git a/module/helpers/dice-helper.js b/module/helpers/dice-helper.js index 228791a..3784511 100644 --- a/module/helpers/dice-helper.js +++ b/module/helpers/dice-helper.js @@ -84,7 +84,7 @@ export default class KHDiceRoller { }); } - async rollSkillInChat(skillName, skillValue, showValue, speaker) { + async rollSkillInChat(skillName, skillValue, showValue, speaker, openclosed) { const roll = new Roll(`1d100`); let res = roll.roll(); @@ -95,16 +95,43 @@ export default class KHDiceRoller { computedName += " (" + skillValue + ")" } + if(openclosed === undefined) { + openclosed = 0 + } + let rollData = { name: computedName, res: res }; if(skillValue > 0) { - if(res.total <= skillValue) { + let oneRes = Math.floor((res.total / 1) % 10); + let tenRes = Math.floor((res.total / 10) % 10); + + if(openclosed < 0) { + rollData.closed = Math.abs(openclosed) + } + + if(openclosed > 0) { + rollData.opened = Math.abs(openclosed) + } + + if(openclosed < 0 && oneRes !== 0 && Math.abs(openclosed) >= oneRes) { + // roll is closed + rollData.failure = true + } else if(openclosed > 0 && oneRes !== 0 && Math.abs(openclosed) >= oneRes){ + // roll is opened rollData.success = true } else { - rollData.failure = true + if (res.total <= skillValue) { + rollData.success = true + } else { + rollData.failure = true + } + } + + if(oneRes === tenRes) { + rollData.excetional = true } } @@ -121,4 +148,101 @@ export default class KHDiceRoller { }, }); } + + async rollSkillDialogInChat(skillName, skillValue, showValue, speaker, startopen) { + const id = randomID(); + + if(startopen === undefined) { + startopen = 0 + } + + const content = await renderTemplate("systems/kopparhavet/templates/roll-dialog.html", { + id, + startopen, + skillName, + skillValue, + }); + + await new Dialog({ + title: game.i18n.localize("ROLL.TITLE"), + content, + buttons: { + one: { + icon: '', + label: game.i18n.localize("BUTTON.ROLL"), + callback: async () => { + const container = document.getElementById(id); + let openclosed = container.querySelector('[name="openclosed"]').value + + const roll = new Roll(`1d100`); + + let res = roll.roll(); + + let computedName = skillName + + if(showValue) { + computedName += " (" + skillValue + ")" + } + + let rollData = { + name: computedName, + res: res + }; + + // Evaluate result only if we have a positive skillvalue + if(skillValue > 0) { + let oneRes = Math.floor((res.total / 1) % 10); + let tenRes = Math.floor((res.total / 10) % 10); + + if(openclosed < 0) { + rollData.closed = Math.abs(openclosed) + } + + if(openclosed > 0) { + rollData.opened = Math.abs(openclosed) + } + + if(openclosed < 0 && oneRes !== 0 && Math.abs(openclosed) >= oneRes) { + // roll is closed + rollData.failure = true + } else if(openclosed > 0 && oneRes !== 0 && Math.abs(openclosed) >= oneRes){ + // roll is opened + rollData.success = true + } else { + if (res.total <= skillValue) { + rollData.success = true + } else { + rollData.failure = true + } + } + + if(oneRes === tenRes) { + rollData.excetional = true + } + } + + const html = await renderTemplate("systems/kopparhavet/templates/dice/roll.html", rollData); + + await roll.toMessage({ + create: true, + content: html, + user: game.user._id, + speaker: { + actor: speaker._id, + token: speaker.token, + alias: speaker.name, + }, + }); + }, + }, + two: { + icon: '', + label: game.i18n.localize("BUTTON.CANCEL"), + }, + }, + }, + { + classes: ["dialog", "kopparhavet"], + }).render(true); + } } \ No newline at end of file diff --git a/module/helpers/migration-helper.js b/module/helpers/migration-helper.js new file mode 100644 index 0000000..28ebcf7 --- /dev/null +++ b/module/helpers/migration-helper.js @@ -0,0 +1,21 @@ +/** + * Perform a system migration for the entire World, applying migrations for Actors, Items, and Compendium packs + * @return {Promise} A Promise which resolves once the migration is completed + */ +export const migrateWorld = async function () { + ui.notifications.info( + `Applying System Migration for version ${game.system.data.version}. Please be patient and do not close your game or shut down your server.`, + {permanent: true} + ); + + // Migrate to v0.0.3 from v0.0.2 and v0.0.1 + game.items.forEach((item) => { + if(item.data.type === "spell") { + item.update({"data.roll.label": "SPELL.ROLLTITLE"}); + } + }); + + // Set the migration as complete + game.settings.set("kopparhavet", "worldSchemaVersion", game.system.data.version); + ui.notifications.info(`System Migration to version ${game.system.data.version} completed!`, { permanent: true }); +}; \ No newline at end of file diff --git a/module/items/item-sheet.js b/module/items/item-sheet.js index a740701..76fa16d 100644 --- a/module/items/item-sheet.js +++ b/module/items/item-sheet.js @@ -36,7 +36,13 @@ export class ItemSheetKH extends ItemSheet { switch (this.object.data.type) { case "weapon": // Load Skills Compendium skills - let skillList2 = await game.packs.get("kopparhavet.skills").getContent(); + let skillList2 + + if(game.settings.get("kopparhavet", "gameSystem") === "hjaltarnas-tid") { + skillList2 = await game.packs.get("kopparhavet.skills-ht").getContent(); + } else { + skillList2 = await game.packs.get("kopparhavet.skills").getContent(); + } for (let item of skillList2) { if(item.data.type === "skill" && item.data.data.type.value === "combat") { @@ -66,6 +72,28 @@ export class ItemSheetKH extends ItemSheet { this.position.width = 405; this.position.height = 570; break; + case "spell": + // Load Skills Compendium skills + let skillList3 + + if(game.settings.get("kopparhavet", "gameSystem") === "hjaltarnas-tid") { + skillList3 = await game.packs.get("kopparhavet.skills-ht").getContent(); + } else { + skillList3 = await game.packs.get("kopparhavet.skills").getContent(); + } + + for (let item of skillList3) { + if(item.data.type === "skill") { + skillList.push(item) + } + } + + // Retrieve any created skills as well + for (let item of game.items.entities) { + if(item.data.type === "skill") { + skillList.push(item) + } + } default: this.position.width = 450; this.position.height = 605; diff --git a/module/kh-hooks.js b/module/kh-hooks.js index 49a7fb0..650d0ce 100644 --- a/module/kh-hooks.js +++ b/module/kh-hooks.js @@ -6,6 +6,9 @@ export default class KHHooks { let actorbaseSkills; if(game.settings.get("kopparhavet", "gameSystem") === "hjaltarnas-tid") { + // Set currency name + actor.update({ "data.currency.shekel.label": "CURRENCY.SILVER" }); + actorbaseSkills = CONFIG.KH.baseSkillsHT skillIndex = await game.packs.get("kopparhavet.skills-ht").getContent(); } else { diff --git a/module/kh-main.js b/module/kh-main.js index 763e905..86d5a46 100644 --- a/module/kh-main.js +++ b/module/kh-main.js @@ -4,6 +4,7 @@ import KHHooks from "./kh-hooks.js"; import { ActorKH } from "./actors/actor.js"; import { ActorSheetKH } from "./actors/actor-sheet.js"; import { KH } from "./kh-config.js"; +import * as migrations from "./helpers/migration-helper.js"; Hooks.once("init", () => { CONFIG.Combat.initiative = { formula: "(@combat.init)d6kh2", decimals: 0 }; @@ -20,7 +21,7 @@ Hooks.once("init", () => { scope: "world", config: true, default: 0, - type: Number, + type: String, }); game.settings.register("kopparhavet", "gameSystem", { name: "Game System", @@ -59,8 +60,6 @@ Hooks.on("createActor", async (actor, options, userId) => KHHooks.onCreateActor( function registerSheets() { // Register sheet application classes - console.log("Registerting sheets") - Actors.unregisterSheet("core", ActorSheet); Actors.registerSheet("kopparhavet", ActorSheetKH, { types: ["character"], makeDefault: true }); Actors.registerSheet("kopparhavet", ActorSheetKH, { types: ["adversary"], makeDefault: true }); @@ -170,6 +169,20 @@ function registerHandlebarsHelpers() { } }); + Handlebars.registerHelper("spellRoll", function (roll) { + roll = normalize(roll, "roll"); + switch (roll) { + case "roll": + return game.i18n.localize("SPELL.ROLL"); + case "attackroll": + return game.i18n.localize("SPELL.ATTACKROLL"); + case "opposite": + return game.i18n.localize("SPELL.OPPOSITE"); + case "ritual": + return game.i18n.localize("SPELL.RITUAL"); + } + }); + Handlebars.registerHelper('plaintextToHTML', function(value) { // strip tags, add
tags return new Handlebars.SafeString(value.replace(/(<([^>]+)>)/gi, "").replace(/(?:\r\n|\r|\n)/g, '
')); @@ -177,12 +190,21 @@ function registerHandlebarsHelpers() { } function migrateWorld() { - game.actors.forEach((actor) => { - // Migrate to v0.0.2 from v0.0.1 - if(actor.data.type === "character") { - if(!actor.data?.data?.bio?.appearance) { - actor.update({"data.bio.appearance.label": "BIO.APPEARANCE", "data.bio.appearance.value": ""}); - } + // Determine whether a system migration is required and feasible + const currentVersion = game.settings.get("kopparhavet", "worldSchemaVersion"); + const NEEDS_MIGRATION_VERSION = "0.0.3"; + const COMPATIBLE_MIGRATION_VERSION = '0' || isNaN('NaN'); + let needMigration = currentVersion < NEEDS_MIGRATION_VERSION || currentVersion === null; + + // Perform the migration + if (needMigration && game.user.isGM) { + if (currentVersion && currentVersion < COMPATIBLE_MIGRATION_VERSION) { + ui.notifications.error( + `Your system data is from a version that cannot be reliably migrated to the latest version. The process will be attempted, but errors may occur.`, + { permanent: true } + ); } - }); + + migrations.migrateWorld(); + } } \ No newline at end of file diff --git a/styles/actors.css b/styles/actors.css index 46296c6..1a86394 100644 --- a/styles/actors.css +++ b/styles/actors.css @@ -188,6 +188,7 @@ } .sheet-tabs { + min-height: 36px; } .relation-list li:not(:last-child) { diff --git a/styles/items.css b/styles/items.css index e8ca394..43472d5 100644 --- a/styles/items.css +++ b/styles/items.css @@ -97,17 +97,24 @@ margin: auto; } -.items .items-list .item { +.items .items-list .item, +.items .items-list .item-spell, +.items .items-list .item-weapon, +.items .items-list .item-skill, +.items .items-list .item-nor, +.items .items-list .item-defence { line-height: 24px; padding: 3px 0; border-bottom: 1px solid #bbb; text-align: center; } -.items .items-list .item .toggle-equipped { +.items .items-list .item .toggle-equipped, +.items .items-list .item-weapon .toggle-equipped { color: #888; } -.items .items-list .item .toggle-equipped.active { +.items .items-list .item .toggle-equipped.active, +.items .items-list .item-weapon .toggle-equipped.active{ color: #191813; -} \ No newline at end of file +} diff --git a/system.json b/system.json index ebc97d9..90b6749 100644 --- a/system.json +++ b/system.json @@ -2,10 +2,10 @@ "name": "kopparhavet", "title": "Kopparhavets Hjältar", "description": "The Molten Sea is a dangerous but exciting place, where pirates, sorcerers and secretive orders of knighthood struggle for power, wealth and ancient lore.", - "version": "0.0.2", + "version": "0.0.3", "minimumCoreVersion": "0.7.5", "compatibleCoreVersion": "0.7.7", - "templateVersion": 3, + "templateVersion": 4, "author": "Erebus", "scripts": [], "esmodules": [ @@ -53,6 +53,6 @@ "url": "https://pi.rikspolisen.se/foundryvtt/kopparhavet", "socket": true, "manifest": "https://pi.rikspolisen.se/foundryvtt/kopparhavet/raw/branch/master/system.json", - "download": "https://pi.rikspolisen.se/foundryvtt/kopparhavet/archive/v0.0.2.zip", + "download": "https://pi.rikspolisen.se/foundryvtt/kopparhavet/archive/v0.0.3.zip", "license": "" } diff --git a/template.json b/template.json index 5806e21..773113b 100644 --- a/template.json +++ b/template.json @@ -230,9 +230,12 @@ "core" ], "roll": { - "value": "", + "value": "roll", "type": "String", - "label": "SPELL.ROLL" + "label": "SPELL.ROLLTITLE", + "skill": "Trolldom", + "oppositeskill": "", + "ritual": {} }, "cost": { "value": "", diff --git a/templates/chat/item-card.html b/templates/chat/item-card.html index 553e89b..ec4f581 100644 --- a/templates/chat/item-card.html +++ b/templates/chat/item-card.html @@ -74,8 +74,7 @@ {{localize data.cost.label}}: {{data.cost.value}} {{localize data.difficulty.label}}: {{rollDifficulty data.difficulty.value}}
- {{localize data.roll.label}} - {{data.roll.value}} + {{localize data.roll.label}}: {{spellRoll data.roll.value}}
{{#if data.description}} diff --git a/templates/dice/roll.html b/templates/dice/roll.html index 1b79561..160d58b 100644 --- a/templates/dice/roll.html +++ b/templates/dice/roll.html @@ -4,6 +4,16 @@
+ {{#if closed}} +
+ {{localize "ROLL.CLOSED"}}: {{closed}} +
+ {{/if}} + {{#if opened}} +
+ {{localize "ROLL.OPENED"}}: {{opened}} +
+ {{/if}}
{{#if showFormula}}
{{res.formula}}
@@ -13,14 +23,14 @@
{{#if success}} -
- {{localize "ROLL.SUCCESS"}} -
+

+ {{#if excetional}}{{localize "ROLL.EXCEPTIONAL"}}{{/if}} {{localize "ROLL.SUCCESS"}} +

{{/if}} {{#if failure}} -
- {{localize "ROLL.FAILURE"}} -
+

+ {{#if excetional}}{{localize "ROLL.EXCEPTIONAL"}}{{/if}} {{localize "ROLL.FAILURE"}} +

{{/if}}
diff --git a/templates/items/spell-sheet.html b/templates/items/spell-sheet.html index 1dc9ee6..23696b6 100644 --- a/templates/items/spell-sheet.html +++ b/templates/items/spell-sheet.html @@ -26,7 +26,24 @@
- + +
+
+ +
@@ -39,4 +56,4 @@
- + \ No newline at end of file diff --git a/templates/parts/actor/combat.html b/templates/parts/actor/combat.html index 64e682d..0202642 100644 --- a/templates/parts/actor/combat.html +++ b/templates/parts/actor/combat.html @@ -2,16 +2,16 @@
- - + +
{{/each}} @@ -79,8 +79,8 @@ {{/if}}
- - + +
{{/each}} @@ -105,8 +105,8 @@
- - + +
{{/each}} diff --git a/templates/parts/actor/ht-combat.html b/templates/parts/actor/ht-combat.html index e287d61..e96173e 100644 --- a/templates/parts/actor/ht-combat.html +++ b/templates/parts/actor/ht-combat.html @@ -2,17 +2,17 @@