From f55fc1d59a9e6da83d651bc339cd9b07408d6c62 Mon Sep 17 00:00:00 2001 From: sladecraven Date: Thu, 4 Aug 2022 16:28:10 +0200 Subject: [PATCH] Add hotbar --- modules/crucible-actor-sheet.js | 6 +-- modules/crucible-actor.js | 24 +++++++++ modules/crucible-commands.js | 4 +- modules/crucible-hotbar.js | 86 ++++++++++++++++++++++++++++++ modules/crucible-main.js | 11 ++-- modules/crucible-utility.js | 7 ++- packs/skills.db | 4 +- system.json | 4 +- templates/actor-sheet.html | 4 +- templates/chat-generic-result.html | 10 +++- templates/roll-dialog-generic.html | 7 +++ 11 files changed, 149 insertions(+), 18 deletions(-) create mode 100644 modules/crucible-hotbar.js diff --git a/modules/crucible-actor-sheet.js b/modules/crucible-actor-sheet.js index 42f7a67..c96ca4d 100644 --- a/modules/crucible-actor-sheet.js +++ b/modules/crucible-actor-sheet.js @@ -153,12 +153,10 @@ export class CrucibleActorSheet extends ActorSheet { this.actor.rollWeapon(skillId) }); html.find('.roll-armor-die').click((event) => { - //TODO - ui.notifications.warn("Not implemented") + this.actor.rollArmorDie() }); html.find('.roll-shield-die').click((event) => { - //TODO - ui.notifications.warn("Not implemented") + this.actor.rollShieldDie() }); html.find('.roll-save').click((event) => { diff --git a/modules/crucible-actor.js b/modules/crucible-actor.js index 48a0b09..a3ee5f4 100644 --- a/modules/crucible-actor.js +++ b/modules/crucible-actor.js @@ -570,6 +570,30 @@ export class CrucibleActor extends Actor { } } } + + /* -------------------------------------------- */ + rollShieldDie() { + let shield = this.getEquippedShield() + if (shield) { + shield = duplicate(shield) + let rollData = this.getCommonRollData() + rollData.mode = "shield" + rollData.shield = shield + rollData.img = shield.img + this.startRoll(rollData) + } + } + + /* -------------------------------------------- */ + rollArmorDie() { + let armor = this.getEquippedArmor() + if (armor) { + armor = duplicate(armor) + let diceValue = armor.data.absorprionroll + + } + } + /* -------------------------------------------- */ rollSave(saveKey) { let saves = this.getSaveRoll() diff --git a/modules/crucible-commands.js b/modules/crucible-commands.js index 5c7b38f..46e237b 100644 --- a/modules/crucible-commands.js +++ b/modules/crucible-commands.js @@ -7,11 +7,11 @@ import { CrucibleRollDialog } from "./crucible-roll-dialog.js"; export class CrucibleCommands { static init() { - if (!game.system.crucible.commands) { + if (!game.system.cruciblerpg.commands) { const crucibleCommands = new CrucibleCommands(); //crucibleCommands.registerCommand({ path: ["/char"], func: (content, msg, params) => crucibleCommands.createChar(msg), descr: "Create a new character" }); //crucibleCommands.registerCommand({ path: ["/pool"], func: (content, msg, params) => crucibleCommands.poolRoll(msg), descr: "Generic Roll Window" }); - game.system.crucible.commands = crucibleCommands; + game.system.cruciblerpg.commands = crucibleCommands; } } constructor() { diff --git a/modules/crucible-hotbar.js b/modules/crucible-hotbar.js new file mode 100644 index 0000000..300889b --- /dev/null +++ b/modules/crucible-hotbar.js @@ -0,0 +1,86 @@ + +export class CrucibleHotbar { + + /** + * Create a macro when dropping an entity on the hotbar + * Item - open roll dialog for item + * Actor - open actor sheet + * Journal - open journal sheet + */ + static init( ) { + + Hooks.on("hotbarDrop", async (bar, documentData, slot) => { + // Create item macro if rollable item - weapon, spell, prayer, trait, or skill + if (documentData.type == "Item") { + console.log("Drop done !!!", bar, documentData, slot) + let item = documentData.data + let command = `game.system.cruciblerpg.CrucibleHotbar.rollMacro("${item.name}", "${item.type}");` + let macro = game.macros.contents.find(m => (m.name === item.name) && (m.command === command)) + if (!macro) { + macro = await Macro.create({ + name: item.name, + type: "script", + img: item.img, + command: command + }, { displaySheet: false }) + } + game.user.assignHotbarMacro(macro, slot); + } + // Create a macro to open the actor sheet of the actor dropped on the hotbar + else if (documentData.type == "Actor") { + let actor = game.actors.get(documentData.id); + let command = `game.actors.get("${documentData.id}").sheet.render(true)` + let macro = game.macros.contents.find(m => (m.name === actor.name) && (m.command === command)); + if (!macro) { + macro = await Macro.create({ + name: actor.data.name, + type: "script", + img: actor.data.img, + command: command + }, { displaySheet: false }) + game.user.assignHotbarMacro(macro, slot); + } + } + // Create a macro to open the journal sheet of the journal dropped on the hotbar + else if (documentData.type == "JournalEntry") { + let journal = game.journal.get(documentData.id); + let command = `game.journal.get("${documentData.id}").sheet.render(true)` + let macro = game.macros.contents.find(m => (m.name === journal.name) && (m.command === command)); + if (!macro) { + macro = await Macro.create({ + name: journal.data.name, + type: "script", + img: "", + command: command + }, { displaySheet: false }) + game.user.assignHotbarMacro(macro, slot); + } + } + return false; + }); + } + + /** Roll macro */ + static rollMacro(itemName, itemType, bypassData) { + const speaker = ChatMessage.getSpeaker() + let actor + if (speaker.token) actor = game.actors.tokens[speaker.token] + if (!actor) actor = game.actors.get(speaker.actor) + if (!actor) { + return ui.notifications.warn(`Select your actor to run the macro`) + } + + let item = actor.items.find(it => it.name === itemName && it.type == itemType) + if (!item ) { + return ui.notifications.warn(`Unable to find the item of the macro in the current actor`) + } + // Trigger the item roll + if (item.type === "weapon") { + return actor.rollWeapon( item.id) + } + if (item.type === "skill") { + return actor.rollSkill( item.id) + } + } + +} diff --git a/modules/crucible-main.js b/modules/crucible-main.js index 0f4f91d..4378e89 100644 --- a/modules/crucible-main.js +++ b/modules/crucible-main.js @@ -15,6 +15,7 @@ import { CrucibleNPCSheet } from "./crucible-npc-sheet.js"; import { CrucibleUtility } from "./crucible-utility.js"; import { CrucibleCombat } from "./crucible-combat.js"; import { CrucibleItem } from "./crucible-item.js"; +import { CrucibleHotbar } from "./crucible-hotbar.js" /* -------------------------------------------- */ /* Foundry VTT Initialization */ @@ -22,7 +23,12 @@ import { CrucibleItem } from "./crucible-item.js"; /************************************************************************************/ Hooks.once("init", async function () { + console.log(`Initializing Crucible RPG`); + + game.system.cruciblerpg = { + CrucibleHotbar + } /* -------------------------------------------- */ // preload handlebars templates @@ -56,7 +62,6 @@ Hooks.once("init", async function () { CONFIG.Actor.documentClass = CrucibleActor CONFIG.Item.documentClass = CrucibleItem //CONFIG.Token.objectClass = CrucibleToken - game.system.crucible = { }; /* -------------------------------------------- */ // Register sheet application classes @@ -67,8 +72,7 @@ Hooks.once("init", async function () { Items.unregisterSheet("core", ItemSheet); Items.registerSheet("fvtt-crucible", CrucibleItemSheet, { makeDefault: true }); - CrucibleUtility.init(); - + CrucibleUtility.init() }); /* -------------------------------------------- */ @@ -103,6 +107,7 @@ Hooks.once("ready", function () { welcomeMessage(); CrucibleUtility.ready() + CrucibleHotbar.init() }) /* -------------------------------------------- */ diff --git a/modules/crucible-utility.js b/modules/crucible-utility.js index 3c4d391..82f5239 100644 --- a/modules/crucible-utility.js +++ b/modules/crucible-utility.js @@ -285,6 +285,9 @@ export class CrucibleUtility { if ( rollData.save) { startFormula = String(rollData.save.value) + "d6cs>=5" } + if ( rollData.shield) { + startFormula = "1" + String(rollData.shield.data.shielddie) + "cs>=5" + } diceFormula = startFormula // skill => 2 @@ -344,7 +347,9 @@ export class CrucibleUtility { // armor => 12 let skillArmorPenalty = 0 for (let armor of rollData.armors) { - skillArmorPenalty += armor.data.skillpenalty + if (armor.data.equipped) { + skillArmorPenalty += armor.data.skillpenalty + } } if (rollData.skill && rollData.skill.data.armorpenalty && skillArmorPenalty > 0 ) { rollData.skillArmorPenalty = skillArmorPenalty diff --git a/packs/skills.db b/packs/skills.db index 3fbc232..bfc16a3 100644 --- a/packs/skills.db +++ b/packs/skills.db @@ -13,7 +13,7 @@ {"_id":"Y4o571K5DQseDaGT","name":"Swim","type":"skill","img":"systems/fvtt-crucible-rpg/images/icons/skills/Swim.webp","data":{"ability":"str","armorpenalty":true,"bonusdice":"","level":0,"background":0,"basic":0,"class":0,"exp":0,"description":"

Kick you feet and don't forget to breathe!

"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Up3b6rNa3VKAFQC3":3},"flags":{}} {"_id":"ZfIwXZwaBKaVoYbG","name":"Athletics","type":"skill","img":"systems/fvtt-crucible-rpg/images/icons/skills/Athletics.png","data":{"ability":"agi","armorpenalty":true,"bonusdice":"none","level":0,"background":0,"basic":0,"class":0,"exp":0,"description":"

Your ability to run, jump, and climb; a measure of your physical coordination.

"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Up3b6rNa3VKAFQC3":3},"flags":{}} {"_id":"cc74gHSQK4hRR8Vj","name":"Brawn","type":"skill","img":"systems/fvtt-crucible-rpg/images/icons/skills/Brawn.png","data":{"ability":"str","armorpenalty":false,"bonusdice":"none","level":0,"background":0,"basic":0,"class":0,"exp":0,"description":"

A combination of your Size and Strength.

"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Up3b6rNa3VKAFQC3":3},"flags":{}} -{"_id":"fJjXMpUILcN983XV","name":"Axe","type":"skill","img":"systems/fvtt-crucible-rpg/images/icons/icon_skill.webp","data":{"ability":"agi","armorpenalty":false,"isproficient":true,"isweaponskill":true,"isshiedskill":false,"isfeatdie":false,"issl2":false,"islore":false,"skilltype":"complex","isinnate":false,"bonusdice":"none","background":0,"basic":0,"class":0,"exp":0,"explevel":0,"description":"","level":2,"isshieldskill":true},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Up3b6rNa3VKAFQC3":3},"flags":{"core":{"sourceId":"Item.Cnw8keaxD1SI3vun"}}} +{"_id":"fJjXMpUILcN983XV","name":"Axe","type":"skill","img":"systems/fvtt-crucible-rpg/images/icons/icon_skill.webp","data":{"ability":"agi","armorpenalty":false,"isproficient":true,"isweaponskill":true,"isshieldskill":true,"isfeatdie":false,"issl2":false,"islore":false,"skilltype":"complex","isinnate":false,"bonusdice":"none","background":0,"basic":0,"class":0,"exp":0,"explevel":0,"description":"","isshiedskill":false,"level":2},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Up3b6rNa3VKAFQC3":3},"flags":{"core":{"sourceId":"Item.Cnw8keaxD1SI3vun"}}} {"_id":"fegRI4Vsyr0Us1Ga","name":"Research","type":"skill","img":"systems/fvtt-crucible-rpg/images/icons/skills/Research.webp","data":{"ability":"int","armorpenalty":false,"bonusdice":"","level":0,"background":0,"basic":0,"class":0,"exp":0,"description":"

Give me a moment to look that up....

"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Up3b6rNa3VKAFQC3":3},"flags":{}} {"_id":"i8eeE2I9vv2kHwdJ","name":"Shadow Lore","type":"skill","img":"systems/fvtt-crucible-rpg/images/icons/skills/Shadow%20Lore.webp","data":{"ability":"int","armorpenalty":true,"bonusdice":"","level":0,"background":0,"basic":0,"class":0,"exp":0,"description":"

You can cast Shadow Lore spells.

"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Up3b6rNa3VKAFQC3":3},"flags":{}} {"_id":"lfB80K2lFSzQH442","name":"Intuition","type":"skill","img":"systems/fvtt-crucible-rpg/images/icons/skills/Intuition.png","data":{"ability":"wit","armorpenalty":false,"bonusdice":"none","level":0,"background":0,"basic":0,"class":0,"exp":0,"description":"

I see what you did there.  I think you're up to something....

"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Up3b6rNa3VKAFQC3":3},"flags":{}} @@ -23,5 +23,3 @@ {"_id":"s2AAQviLttcHul3X","name":"Charm","type":"skill","img":"systems/fvtt-crucible-rpg/images/icons/skills/Charm.png","data":{"ability":"cha","armorpenalty":false,"bonusdice":"none","level":0,"background":0,"basic":0,"class":0,"exp":0,"description":"

Getting someone to do what you want because they want to do it.

"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Up3b6rNa3VKAFQC3":3},"flags":{}} {"_id":"xlYUHAUSfQrsjQoi","name":"Survival","type":"skill","img":"systems/fvtt-crucible-rpg/images/icons/skills/Survival.webp","data":{"ability":"wit","armorpenalty":false,"bonusdice":"","level":0,"background":0,"basic":0,"class":0,"exp":0,"description":"

Help me set this snare and we'll eat like kings in the morning.

"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Up3b6rNa3VKAFQC3":3},"flags":{}} {"_id":"yAhtkgqf7pKyjJTA","name":"Poison Use","type":"skill","img":"systems/fvtt-crucible-rpg/images/icons/skills/Poison%20Use.webp","data":{"ability":"dex","armorpenalty":false,"bonusdice":"","level":0,"background":0,"basic":0,"class":0,"exp":0,"description":"

Let me apply this to my blade.

"},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Up3b6rNa3VKAFQC3":3},"flags":{}} -{"_id":"fJjXMpUILcN983XV","name":"Axe","type":"skill","img":"systems/fvtt-crucible-rpg/images/icons/icon_skill.webp","data":{"ability":"agi","armorpenalty":false,"isproficient":true,"isweaponskill":true,"isshieldskill":false,"isfeatdie":false,"issl2":false,"islore":false,"skilltype":"complex","isinnate":false,"bonusdice":"none","background":0,"basic":0,"class":0,"exp":0,"explevel":0,"description":"","isshiedskill":false,"level":2},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Up3b6rNa3VKAFQC3":3},"flags":{"core":{"sourceId":"Item.Cnw8keaxD1SI3vun"}}} -{"_id":"fJjXMpUILcN983XV","name":"Axe","type":"skill","img":"systems/fvtt-crucible-rpg/images/icons/icon_skill.webp","data":{"ability":"agi","armorpenalty":false,"isproficient":true,"isweaponskill":true,"isshieldskill":true,"isfeatdie":false,"issl2":false,"islore":false,"skilltype":"complex","isinnate":false,"bonusdice":"none","background":0,"basic":0,"class":0,"exp":0,"explevel":0,"description":"","isshiedskill":false,"level":2},"effects":[],"folder":null,"sort":0,"permission":{"default":0,"Up3b6rNa3VKAFQC3":3},"flags":{"core":{"sourceId":"Item.Cnw8keaxD1SI3vun"}}} diff --git a/system.json b/system.json index fb1980e..116a9c3 100644 --- a/system.json +++ b/system.json @@ -202,8 +202,8 @@ ] } ], - "primaryTokenAttribute": "secondary.health", - "secondaryTokenAttribute": "secondary.delirium", + "primaryTokenAttribute": "secondary.hp", + "secondaryTokenAttribute": "secondary.effort", "socket": true, "styles": [ "styles/simple.css" diff --git a/templates/actor-sheet.html b/templates/actor-sheet.html index 1c928c5..8d95ee2 100644 --- a/templates/actor-sheet.html +++ b/templates/actor-sheet.html @@ -55,7 +55,7 @@
  • -

    {{ability-margin.name}}

    +

    {{equippedShield.name}}

  • {{/if}} @@ -88,7 +88,7 @@ {{!-- Skills Tab --}}
    -