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}}