forked from public/bol
Add HUD actions
This commit is contained in:
parent
fff6b2a733
commit
a5ba6d5215
40
css/bol.css
40
css/bol.css
@ -982,3 +982,43 @@ body.system-bol img#logo {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/** HUD SECTION */
|
||||
.tokenhudext {
|
||||
display: flex;
|
||||
flex: 0 !important;
|
||||
font-family: CaslonPro;
|
||||
font-weight: 600;
|
||||
}
|
||||
.tokenhudext.left {
|
||||
justify-content: flex-start;
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
top: 2.75rem;
|
||||
right: 4rem;
|
||||
}
|
||||
.tokenhudext.right {
|
||||
justify-content: flex-start;
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
top: 2.75rem;
|
||||
left: 4rem;
|
||||
}
|
||||
.control-icon.tokenhudicon {
|
||||
width: fit-content;
|
||||
height: fit-content;
|
||||
min-width: 6rem;
|
||||
flex-basis: auto;
|
||||
padding: 0;
|
||||
line-height: 1rem;
|
||||
margin: 0.25rem;
|
||||
}
|
||||
.control-icon.tokenhudicon.right {
|
||||
margin-left: 8px;
|
||||
}
|
||||
#token-hud .status-effects.active{
|
||||
z-index: 2;
|
||||
}
|
||||
.bol-hud-menu label {
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
@ -192,24 +192,23 @@ export class BoLActorSheet extends ActorSheet {
|
||||
event.preventDefault();
|
||||
const element = event.currentTarget
|
||||
const dataset = element.dataset
|
||||
const actorData = this.getData()
|
||||
const rollType = dataset.rollType
|
||||
const li = $(event.currentTarget).closest(".item")
|
||||
switch (rollType) {
|
||||
case "attribute":
|
||||
BoLRoll.attributeCheck(this.actor, actorData, dataset, event);
|
||||
BoLRoll.attributeCheck(this.actor, dataset.key, event)
|
||||
break;
|
||||
case "aptitude":
|
||||
BoLRoll.aptitudeCheck(this.actor, actorData, dataset, event);
|
||||
BoLRoll.aptitudeCheck(this.actor, dataset.key, event)
|
||||
break;
|
||||
case "weapon":
|
||||
BoLRoll.weaponCheck(this.actor, actorData, dataset, event);
|
||||
BoLRoll.weaponCheck(this.actor, event)
|
||||
break;
|
||||
case "spell":
|
||||
BoLRoll.spellCheck(this.actor, actorData, dataset, event);
|
||||
BoLRoll.spellCheck(this.actor, event)
|
||||
break;
|
||||
case "alchemy":
|
||||
BoLRoll.alchemyCheck(this.actor, actorData, dataset, event);
|
||||
BoLRoll.alchemyCheck(this.actor, event)
|
||||
break;
|
||||
case "protection":
|
||||
this.actor.rollProtection(li.data("item-id"))
|
||||
|
@ -453,6 +453,27 @@ export class BoLActor extends Actor {
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------- */
|
||||
buildRollList() {
|
||||
let rolls = []
|
||||
for ( let key in this.data.data.attributes) {
|
||||
let attr = this.data.data.attributes[key]
|
||||
rolls.push( { key: key, value: attr.value, name: attr.label, type: "attribute"})
|
||||
}
|
||||
for ( let key in this.data.data.aptitudes) {
|
||||
if ( key != "def") {
|
||||
let apt = this.data.data.aptitudes[key]
|
||||
rolls.push( { key: key, value: apt.value, name: apt.label, type: "aptitude"})
|
||||
}
|
||||
}
|
||||
return rolls
|
||||
}
|
||||
|
||||
/*-------------------------------------------- */
|
||||
buildListeActions() {
|
||||
return this.melee.concat(this.ranged)
|
||||
}
|
||||
|
||||
/*-------------------------------------------- */
|
||||
async manageHealthState() {
|
||||
let hpID = "lastHP" + this.id
|
||||
|
@ -1,16 +1,19 @@
|
||||
/* -------------------------------------------- */
|
||||
// Import Modules
|
||||
import { BoLActor } from "./actor/actor.js";
|
||||
import { BoLActorSheet } from "./actor/actor-sheet.js";
|
||||
import { BoLItem } from "./item/item.js";
|
||||
import { BoLItemSheet } from "./item/item-sheet.js";
|
||||
import { System, BOL } from "./system/config.js";
|
||||
import { preloadHandlebarsTemplates } from "./system/templates.js";
|
||||
import { registerHandlebarsHelpers } from "./system/helpers.js";
|
||||
import registerHooks from "./system/hooks.js";
|
||||
import { Macros } from "./system/macros.js";
|
||||
import { BoLUtility } from "./system/bol-utility.js";
|
||||
import { BoLCombatManager } from "./system/bol-combat.js";
|
||||
import { BoLActor } from "./actor/actor.js"
|
||||
import { BoLActorSheet } from "./actor/actor-sheet.js"
|
||||
import { BoLItem } from "./item/item.js"
|
||||
import { BoLItemSheet } from "./item/item-sheet.js"
|
||||
import { System, BOL } from "./system/config.js"
|
||||
import { preloadHandlebarsTemplates } from "./system/templates.js"
|
||||
import { registerHandlebarsHelpers } from "./system/helpers.js"
|
||||
import registerHooks from "./system/hooks.js"
|
||||
import { Macros } from "./system/macros.js"
|
||||
import { BoLUtility } from "./system/bol-utility.js"
|
||||
import { BoLCombatManager } from "./system/bol-combat.js"
|
||||
import { BoLTokenHud } from "./system/bol-action-hud.js"
|
||||
|
||||
/* -------------------------------------------- */
|
||||
Hooks.once('init', async function () {
|
||||
|
||||
game.bol = {
|
||||
@ -47,7 +50,8 @@ Hooks.once('init', async function () {
|
||||
Items.registerSheet("bol", BoLItemSheet, { makeDefault: true });
|
||||
|
||||
// Inot useful stuff
|
||||
BoLUtility.init();
|
||||
BoLUtility.init()
|
||||
BoLTokenHud.init()
|
||||
|
||||
// Preload Handlebars Templates
|
||||
await preloadHandlebarsTemplates();
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { BoLUtility } from "../system/bol-utility.js";
|
||||
|
||||
const __adv2dice = { ["1B"]: 3, ["2B"]: 4, ["2"]: 2, ["1M"]: 3, ["2M"]: 4 }
|
||||
const _apt2attr = { init: "mind", melee: "agility", ranged: "agility", def: "vigor" }
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -11,57 +10,45 @@ export class BoLRoll {
|
||||
return { classes: ["bol", "dialog"], width: 480, height: 540 };
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static convertToAdv(adv) {
|
||||
if (adv == 0) return "2"
|
||||
return Math.abs(adv) + (adv < 0) ? 'M' : 'B';
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
static getDefaultAttribute(key) {
|
||||
return _apt2attr[key]
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static attributeCheck(actor, actorData, dataset, event) {
|
||||
const key = dataset.key
|
||||
const adv = dataset.adv
|
||||
static attributeCheck(actor, key ) {
|
||||
|
||||
let attribute = eval(`actor.data.data.attributes.${key}`)
|
||||
let label = (attribute.label) ? game.i18n.localize(attribute.label) : null
|
||||
let description = actor.name + " - " + game.i18n.localize('BOL.ui.attributeCheck') + " - " + game.i18n.localize(attribute.label)
|
||||
let description = game.i18n.localize('BOL.ui.attributeCheck') + " - " + game.i18n.localize(attribute.label)
|
||||
|
||||
let rollData = {
|
||||
mode: "attribute",
|
||||
actor: actor,
|
||||
actorData: actorData,
|
||||
attribute: attribute,
|
||||
attrValue: attribute.value,
|
||||
aptValue: 0,
|
||||
label: label,
|
||||
careerBonus: 0,
|
||||
description: description,
|
||||
adv: this.convertToAdv(adv),
|
||||
mod: 0
|
||||
}
|
||||
return this.displayRollDialog( rollData )
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static aptitudeCheck(actor, actorData, dataset, event) {
|
||||
const key = dataset.key;
|
||||
const adv = dataset.adv;
|
||||
static aptitudeCheck(actor, key ) {
|
||||
|
||||
let aptitude = eval(`actor.data.data.aptitudes.${key}`);
|
||||
let aptitude = eval(`actor.data.data.aptitudes.${key}`)
|
||||
let attrKey = this.getDefaultAttribute(key)
|
||||
let attribute = eval(`actor.data.data.attributes.${attrKey}`);
|
||||
let attribute = eval(`actor.data.data.attributes.${attrKey}`)
|
||||
|
||||
let label = (aptitude.label) ? game.i18n.localize(aptitude.label) : null;
|
||||
let description = actor.name + " - " + game.i18n.localize('BOL.ui.aptitudeCheck') + " - " + game.i18n.localize(aptitude.label);
|
||||
let description = game.i18n.localize('BOL.ui.aptitudeCheck') + " - " + game.i18n.localize(aptitude.label);
|
||||
return this.displayRollDialog(
|
||||
{
|
||||
mode: "aptitude",
|
||||
actor: actor,
|
||||
actorData: actorData,
|
||||
attribute: attribute,
|
||||
aptitude: aptitude,
|
||||
attrValue: attribute.value,
|
||||
@ -69,20 +56,15 @@ export class BoLRoll {
|
||||
label: label,
|
||||
careerBonus: 0,
|
||||
description: description,
|
||||
adv: this.convertToAdv(adv),
|
||||
mod: 0
|
||||
});
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static weaponCheck(actor, actorData, dataset, event) {
|
||||
static weaponCheckWithWeapon(actor, weapon) {
|
||||
|
||||
let target = BoLUtility.getTarget()
|
||||
const li = $(event.currentTarget).parents(".item")
|
||||
const weapon = actor.items.get(li.data("item-id"))
|
||||
if (!weapon) {
|
||||
ui.notifications.warn("Unable to find weapon !")
|
||||
return;
|
||||
}
|
||||
|
||||
let weaponData = weapon.data.data
|
||||
let attribute = eval(`actor.data.data.attributes.${weaponData.properties.attackAttribute}`)
|
||||
let aptitude = eval(`actor.data.data.aptitudes.${weaponData.properties.attackAptitude}`)
|
||||
@ -97,7 +79,6 @@ export class BoLRoll {
|
||||
let rolldata = {
|
||||
mode: "weapon",
|
||||
actor: actor,
|
||||
actorData: actorData,
|
||||
weapon: weapon,
|
||||
isRanged: weaponData.properties.ranged || weaponData.properties.throwing,
|
||||
target: target,
|
||||
@ -111,13 +92,23 @@ export class BoLRoll {
|
||||
mod: 0,
|
||||
modRanged: 0,
|
||||
label: (weapon.name) ? weapon.name : game.i18n.localize('BOL.ui.noWeaponName'),
|
||||
description: actor.name + " - " + game.i18n.localize('BOL.ui.weaponAttack'),
|
||||
description: game.i18n.localize('BOL.ui.weaponAttack') + " : " + weapon.name,
|
||||
}
|
||||
return this.displayRollDialog(rolldata)
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
static weaponCheck(actor, event) {
|
||||
const li = $(event.currentTarget).parents(".item")
|
||||
const weapon = actor.items.get(li.data("item-id"))
|
||||
if (!weapon) {
|
||||
ui.notifications.warn("Unable to find weapon !")
|
||||
return
|
||||
}
|
||||
return this.weaponCheckWithWeapon(actor, weapon)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static alchemyCheck(actor, actorData, dataset, event) {
|
||||
static alchemyCheck(actor, event) {
|
||||
const li = $(event.currentTarget).parents(".item");
|
||||
const alchemy = actor.items.get(li.data("item-id"));
|
||||
if (!alchemy) {
|
||||
@ -133,7 +124,6 @@ export class BoLRoll {
|
||||
let alchemyDef = {
|
||||
mode: "alchemy",
|
||||
actor: actor,
|
||||
actorData: actorData,
|
||||
alchemy: alchemy,
|
||||
attribute: actor.data.data.attributes.mind,
|
||||
attrValue: actor.data.data.attributes.mind.value,
|
||||
@ -143,7 +133,7 @@ export class BoLRoll {
|
||||
pcCostCurrent: Number(alchemyData.properties.pccurrent),
|
||||
mod: Number(alchemyData.properties.difficulty),
|
||||
label: alchemy.name,
|
||||
description: actor.name + " - " + game.i18n.localize('BOL.ui.makeAlchemy'),
|
||||
description: game.i18n.localize('BOL.ui.makeAlchemy') + "+" + alchemy.name,
|
||||
}
|
||||
console.log("ALCHEMY!", alchemyDef);
|
||||
return this.displayRollDialog(alchemyDef);
|
||||
@ -151,7 +141,7 @@ export class BoLRoll {
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static spellCheck(actor, actorData, dataset, event) {
|
||||
static spellCheck(actor, event) {
|
||||
if (actor.data.data.resources.power.value <= 0) {
|
||||
ui.notifications.warn("Plus assez de points de Pouvoir !")
|
||||
return
|
||||
@ -166,7 +156,6 @@ export class BoLRoll {
|
||||
let spellDef = {
|
||||
mode: "spell",
|
||||
actor: actor,
|
||||
actorData: actorData,
|
||||
spell: spell,
|
||||
attribute: actor.data.data.attributes.mind,
|
||||
attrValue: actor.data.data.attributes.mind.value,
|
||||
@ -176,7 +165,7 @@ export class BoLRoll {
|
||||
ppCost: Number(spell.data.data.properties.ppcost),
|
||||
mod: Number(spellData.properties.difficulty),
|
||||
label: spell.name,
|
||||
description: actor.name + " - " + game.i18n.localize('BOL.ui.focusSpell'),
|
||||
description: game.i18n.localize('BOL.ui.focusSpell') + " : " + spell.name,
|
||||
}
|
||||
console.log("SPELL!", spellDef);
|
||||
return this.displayRollDialog(spellDef);
|
||||
@ -319,7 +308,7 @@ export class BoLRoll {
|
||||
|
||||
// initialize default flags/values
|
||||
const rollOptionTpl = `systems/bol/templates/dialogs/${rollData.mode}-roll-dialog.hbs`
|
||||
rollData.careers = rollData.actorData.features.careers
|
||||
rollData.careers = rollData.actor.careers
|
||||
rollData.boons = rollData.actor.bonusBoons
|
||||
rollData.flaws = rollData.actor.malusFlaws
|
||||
rollData.defence = 0
|
||||
|
88
module/system/bol-action-hud.js
Normal file
88
module/system/bol-action-hud.js
Normal file
@ -0,0 +1,88 @@
|
||||
/* -------------------------------------------- */
|
||||
import { BoLRoll } from "../controllers/bol-rolls.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class BoLTokenHud {
|
||||
|
||||
static init() {
|
||||
// Integration du TokenHUD
|
||||
Hooks.on('renderTokenHUD', (app, html, data) => { BoLTokenHud.addTokenHudExtensions(app, html, data._id) });
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async removeExtensionHud(app, html, tokenId) {
|
||||
html.find('.control-icon.bol-roll').remove()
|
||||
html.find('.control-icon.bol-action').remove()
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async addExtensionHud(app, html, tokenId) {
|
||||
|
||||
let token = canvas.tokens.get(tokenId)
|
||||
let actor = token.actor
|
||||
app.hasExtension = true
|
||||
|
||||
const hudData = { actor: actor, actionsList: actor.buildListeActions(), rollsList: actor.buildRollList() }
|
||||
|
||||
const controlIconActions = html.find('.control-icon[data-action=combat]');
|
||||
// initiative
|
||||
await BoLTokenHud._configureSubMenu(controlIconActions, 'systems/bol/templates/token/hud-actor-actions.hbs', hudData,
|
||||
(event) => {
|
||||
let actionIndex = Number(event.currentTarget.attributes['data-action-index'].value)
|
||||
let action = hudData.actionsList[actionIndex]
|
||||
const weapon = actor.items.get( action._id )
|
||||
BoLRoll.weaponCheckWithWeapon(hudData.actor, weapon)
|
||||
//console.log("Clicked", action)
|
||||
} )
|
||||
|
||||
const controlIconTarget = html.find('.control-icon[data-action=target]');
|
||||
// att+apt+career
|
||||
await BoLTokenHud._configureSubMenu(controlIconTarget, 'systems/bol/templates/token/hud-actor-rolls.hbs', hudData,
|
||||
(event) => {
|
||||
let rollIndex = Number(event.currentTarget.attributes['data-roll-index'].value)
|
||||
let roll = hudData.rollsList[rollIndex]
|
||||
if ( roll.type == "aptitude") {
|
||||
BoLRoll.aptitudeCheck(actor, roll.key )
|
||||
} else if ( roll.type == "attribute") {
|
||||
BoLRoll.attributeCheck(actor, roll.key )
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async addTokenHudExtensions(app, html, tokenId) {
|
||||
const controlIconCombat = html.find('.control-icon[data-action=combat]')
|
||||
if (controlIconCombat.length>0 ) {
|
||||
BoLTokenHud.addExtensionHud(app, html, tokenId);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async _configureSubMenu(insertionPoint, template, hudData, onMenuItem) {
|
||||
const hud = $(await renderTemplate(template, hudData))
|
||||
const list = hud.find('div.bol-hud-list')
|
||||
|
||||
BoLTokenHud._toggleHudListActive(hud, list);
|
||||
|
||||
hud.find('img.bol-hud-togglebutton').click(event => BoLTokenHud._toggleHudListActive(hud, list));
|
||||
list.find('.bol-hud-menu').click(onMenuItem);
|
||||
|
||||
insertionPoint.after(hud);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static _showControlWhen(control, condition) {
|
||||
if (condition) {
|
||||
control.show()
|
||||
}
|
||||
else {
|
||||
control.hide()
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static _toggleHudListActive(hud, list) {
|
||||
hud.toggleClass('active')
|
||||
BoLTokenHud._showControlWhen(list, hud.hasClass('active'))
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
"url": "https://github.com/ZigmundKreud/bol",
|
||||
"license": "LICENSE.txt",
|
||||
"flags": {},
|
||||
"version": "1.2.4",
|
||||
"version": "1.2.6",
|
||||
"templateVersion": 22,
|
||||
"minimumCoreVersion": "0.8.6",
|
||||
"compatibleCoreVersion": "9",
|
||||
|
10
templates/token/hud-actor-actions.hbs
Normal file
10
templates/token/hud-actor-actions.hbs
Normal file
@ -0,0 +1,10 @@
|
||||
<div class="control-icon bol-action ">
|
||||
<img class="bol-hud-togglebutton" src="icons/svg/sword.svg" width="36" height="36" title="Action" />
|
||||
<div class="bol-hud-list tokenhudext right">
|
||||
{{#each actionsList as |action key|}}
|
||||
<div class="control-icon tokenhudicon bol-hud-menu" data-action-index="{{key}}" title="{{action.name}}">
|
||||
<label>{{action.name}}</label>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
10
templates/token/hud-actor-rolls.hbs
Normal file
10
templates/token/hud-actor-rolls.hbs
Normal file
@ -0,0 +1,10 @@
|
||||
<div class="control-icon bol-roll ">
|
||||
<img class="bol-hud-togglebutton" src="icons/svg/dice-target.svg" width="36" height="36" title="Jets" />
|
||||
<div class="bol-hud-list tokenhudext left">
|
||||
{{#each rollsList as |roll key|}}
|
||||
<div class="control-icon tokenhudicon bol-hud-menu" data-roll-index="{{key}}" title="{{localize roll.name}}">
|
||||
<label>{{ localize roll.name}}</label>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
Loading…
Reference in New Issue
Block a user