Compare commits

...

No commits in common. "main" and "d09d0905b3c0586c2e2833f7a746ed6ef3d46ba2" have entirely different histories.

11 changed files with 86 additions and 255 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5 MiB

View file

@ -1,102 +0,0 @@
name: Create Module Files For GitHub Release
env:
# The URL used for the module's "Project URL" link on FoundryVTT's website.
project_url: "https://github.com/${{github.repository}}"
# A URL that will always point to the latest manifest.
# FoundryVTT uses this URL to check whether the current module version that
# is installed is the latest version. This URL should NOT change,
# otherwise FoundryVTT won't be able to perform this check.
latest_manifest_url: "https://github.com/${{github.repository}}/releases/latest/download/module.json"
# The URL to the module archive associated with the module release being
# processed by this workflow.
release_module_url: "https://github.com/${{github.repository}}/releases/download/${{github.event.release.tag_name}}/module.zip"
on:
# Only run this workflow when a release is published.
# To modify this workflow when other events occur, see:
# - https://docs.github.com/en/actions/using-workflows/triggering-a-workflow
# - https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows
# - https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on
#
# Note that some steps may depend on context variables that are only
# available for release events, so if you add other events, you may need to
# alter other parts of this workflow.
release:
types: [published]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout Repository
uses: actions/checkout@v3
# Extract version embedded in the tag.
# This step expects the tag to be one of the following formats:
# - "v<major>.<minor>.<patch>" (e.g., "v1.2.3")
# - "<major>.<minor>.<patch>" (e.g., "1.2.3")
#
# The version will be used by later steps to fill in the value for the
# "version" key required for a valid module manifest.
- name: Extract Version From Tag
id: get_version
uses: battila7/get-version-action@v2
# Modify "module.json" with values specific to the release.
# Since the values for the "version" and "url" keys aren't known ahead of
# time, the manifest file in the repository is updated with these values.
#
# While this does modify the manifest file in-place, the changes are not
# commited to the repository, and only exist in the action's filesystem.
- name: Modify Module Manifest With Release-Specific Values
id: sub_manifest_link_version
uses: cschleiden/replace-tokens@v1
with:
files: 'module.json'
env:
VERSION: ${{steps.get_version.outputs.version-without-v}}
URL: ${{ env.project_url }}
MANIFEST: ${{ env.latest_manifest_url }}
DOWNLOAD: ${{ env.release_module_url }}
# Create a "module.zip" archive containing all the module's required files.
# If you have other directories or files that will need to be added to
# your packaged module, add them here.
- name: Create Module Archive
run: |
# Note that `zip` will only emit warnings when a file or directory
# doesn't exist, it will not fail.
zip \
`# Options` \
--recurse-paths \
`# The name of the output file` \
./module.zip \
`# The files that will be included.` \
module.json \
readme.md \
LICENSE \
languages/ \
scripts/ \
styles/ \
# Don't forget to add a backslash at the end of the line for any
# additional files or directories!
# Update the GitHub release with the manifest and module archive files.
- name: Update Release with Files
id: create_version_release
uses: ncipollo/release-action@v1
with:
allowUpdates: true
name: ${{ github.event.release.name }}
draft: ${{ github.event.release.unpublished }}
prerelease: ${{ github.event.release.prerelease }}
token: ${{ secrets.GITHUB_TOKEN }}
artifacts: './module.json, ./module.zip'
tag: ${{ github.event.release.tag_name }}
body: ${{ github.event.release.body }}

2
.gitignore vendored
View file

@ -1,4 +1,4 @@
node_modules/* node_modules/*
.vscode/ .vscode/
mkzip.sh mkzip.sh
*.zip *.zip

View file

@ -1,5 +0,0 @@
{
"githubPullRequests.ignoredPullRequestBranches": [
"master"
]
}

View file

@ -4,13 +4,13 @@
"description": "Token Action HUD is a repositionable HUD of actions for a selected token", "description": "Token Action HUD is a repositionable HUD of actions for a selected token",
"authors": [ "authors": [
{ {
"name": "neillc", "name": "Neill Cox",
"url": "https://git.evatt.ingenious.com.au/neillc" "url": "https://github.com/neillc"
} }
], ],
"url": "https://git.evatt.ingenious.com.au/neillc/token-action-hud-gurps", "url": "This is auto replaced",
"flags": {}, "flags": {},
"version": "0.0.100", "version": "0.0.97",
"compatibility": { "compatibility": {
"minimum": "11", "minimum": "11",
"verified": "11.351" "verified": "11.351"
@ -63,9 +63,9 @@
} }
}, },
"socket": false, "socket": false,
"readme": "https://git.evatt.ingenious.com.au/neillc/token-action-hud-gurps/releases/download/0.0.100/readme.md", "readme": "http://172.23.0.17:8000/module.json",
"manifest": "https://git.evatt.ingenious.com.au/neillc/token-action-hud-gurps/releases/download/0.0.100/module.json", "manifest": "http://172.23.0.17:8000/module.json",
"download": "https://git.evatt.ingenious.com.au/neillc/token-action-hud-gurps/releases/download/0.0.100/fvtt-token-action-hud-gurps.zip", "download": "http://172.23.0.17:8000/fvtt-token-action-hud-gurps.zip",
"protected": false, "protected": false,
"coreTranslation": false, "coreTranslation": false,
"library": false "library": false

View file

@ -1,11 +1,14 @@
# Token Action HUD for GURPS ![Downloads](https://img.shields.io/github/downloads/Larkinabout/fvtt-token-action-hud-template/latest/module.zip?color=2b82fc&label=DOWNLOADS&style=for-the-badge) [![Forge Installs](https://img.shields.io/badge/dynamic/json?label=Forge%20Installs&query=package.installs&suffix=%25&url=https%3A%2F%2Fforge-vtt.com%2Fapi%2Fbazaar%2Fpackage%2Ftoken-action-hud-template&colorB=448d34&style=for-the-badge)](https://forge-vtt.com/bazaar#package=token-action-hud-template)
Token Action HUD is a repositionable HUD of actions for a selected token for the GURPS game system. # Token Action HUD Template
This should be considered beta software at the moment. I think it's safe to use, but be careful! Token Action HUD is a repositionable HUD of actions for a selected token.
![Token Action HUD](.github/readme/token-action-hud.gif)
# Features # Features
- Make rolls directly from the HUD instead of opening your character sheet. - Make rolls directly from the HUD instead of opening your character sheet.
- Use items from the HUD or right-click an item to open its sheet.
- Move the HUD and choose to expand the menus up or down. - Move the HUD and choose to expand the menus up or down.
- Unlock the HUD to customise layout and groups per user, and actions per actor. - Unlock the HUD to customise layout and groups per user, and actions per actor.
- Add your own macros, journal entries and roll table compendiums. - Add your own macros, journal entries and roll table compendiums.
@ -15,18 +18,18 @@ This should be considered beta software at the moment. I think it's safe to use,
## Method 1 ## Method 1
1. On Foundry VTT's **Configuration and Setup** screen, go to **Add-on Modules** 1. On Foundry VTT's **Configuration and Setup** screen, go to **Add-on Modules**
2. Click **Install Module** 2. Click **Install Module**
3. Search for **Token Action HUD for GURPS** 3. Search for **Token Action HUD Pathfinder 2**
4. Click **Install** next to the module listing 4. Click **Install** next to the module listing
## Method 2 ## Method 2
1. On Foundry VTT's **Configuration and Setup** screen, go to **Add-on Modules** 1. On Foundry VTT's **Configuration and Setup** screen, go to **Add-on Modules**
2. Click **Install Module** 2. Click **Install Module**
3. In the Manifest URL field, paste: `https://git.evatt.ingenious.com.au/neillc/token-action-hud-gurps/releases/download/latest/module.json` 3. In the Manifest URL field, paste: `https://github.com/Larkinabout/fvtt-token-action-hud-template/releases/latest/download/module.json`
4. Click **Install** next to the pasted Manifest URL 4. Click **Install** next to the pasted Manifest URL
## Required Modules ## Required Modules
**IMPORTANT** - Token Action HUD for GURPS requires the [Token Action HUD Core](https://foundryvtt.com/packages/token-action-hud-core) module to be installed. **IMPORTANT** - Token Action HUD Template requires the [Token Action HUD Core](https://foundryvtt.com/packages/token-action-hud-core) module to be installed.
## Recommended Modules ## Recommended Modules
Token Action HUD uses the [Color Picker](https://foundryvtt.com/packages/color-picker) library module for its color picker settings. Token Action HUD uses the [Color Picker](https://foundryvtt.com/packages/color-picker) library module for its color picker settings.
@ -35,7 +38,7 @@ Token Action HUD uses the [Color Picker](https://foundryvtt.com/packages/color-p
For a guide on using Token Action HUD, go to: [How to Use Token Action HUD](https://github.com/Larkinabout/fvtt-token-action-hud-core/wiki/How-to-Use-Token-Action-HUD) For a guide on using Token Action HUD, go to: [How to Use Token Action HUD](https://github.com/Larkinabout/fvtt-token-action-hud-core/wiki/How-to-Use-Token-Action-HUD)
For questions, feature requests or bug reports, please open an issue [here](https://git.evatt.ingenious.com.au/neillc/token-action-hud-gurps/issues). For questions, feature requests or bug reports, please open an issue [here](https://github.com/Larkinabout/fvtt-token-action-hud-core/issues).
Pull requests are welcome. Please include a reason for the request or create an issue before starting one. Pull requests are welcome. Please include a reason for the request or create an issue before starting one.
@ -45,4 +48,4 @@ Thank you to the Community Helpers on Foundry's Discord who provide tireless sup
# License # License
This Foundry VTT module is licensed under a [Creative Commons Attribution 4.0 International License](https://creativecommons.org/licenses/by/4.0/) and this work is licensed under [Foundry Virtual Tabletop EULA - Limited License Agreement for module development](https://foundryvtt.com/article/license/). This Foundry VTT module is licensed under a [Creative Commons Attribution 4.0 International License](https://creativecommons.org/licenses/by/4.0/) and this work is licensed under [Foundry Virtual Tabletop EULA - Limited License Agreement for module development](https://foundryvtt.com/article/license/).

View file

@ -9,11 +9,11 @@ export default [
'scripts/*/*.js' 'scripts/*/*.js'
], ],
exclude: [ exclude: [
'scripts/token-action-hud-template.min.js'] 'scripts/token-action-hud-gurps.min.js']
}, },
output: { output: {
format: 'esm', format: 'esm',
file: 'scripts/token-action-hud-template.min.js' file: 'scripts/token-action-hud-gurps.min.js'
}, },
plugins: [ plugins: [
terser({ keep_classnames: true, keep_fnames: true }), terser({ keep_classnames: true, keep_fnames: true }),

View file

@ -32,6 +32,7 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
} }
if (this.actorType === 'character') { if (this.actorType === 'character') {
//debugger;
this.#buildCharacterActions() this.#buildCharacterActions()
} else if (!this.actor) { } else if (!this.actor) {
this.#buildMultipleTokenActions() this.#buildMultipleTokenActions()
@ -43,6 +44,7 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
* @private * @private
*/ */
#buildCharacterActions () { #buildCharacterActions () {
// debugger;
this._get_attributes({id: "attributes", type:"system"}) this._get_attributes({id: "attributes", type:"system"})
this._get_skills({id: "skills", type:"system"}) this._get_skills({id: "skills", type:"system"})
this._get_spells({id: "spells", type:"system"}) this._get_spells({id: "spells", type:"system"})
@ -79,6 +81,7 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
} }
_get_melee_attacks(parent) { _get_melee_attacks(parent) {
// debugger;
const macroType = "melee"; const macroType = "melee";
let actions = []; let actions = [];
@ -109,6 +112,7 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
} }
_get_ranged_attacks(parent) { _get_ranged_attacks(parent) {
// debugger;
const macroType = "ranged"; const macroType = "ranged";
let actions = []; let actions = [];
@ -139,146 +143,57 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
} }
_get_skills(parent) { _get_skills(parent) {
// debugger;
const macroType = "skills"; const macroType = "skills";
let actions = []; let actions = [];
// let skills = Object.entries(this.actor.system.skills)
// skills.forEach((a) => {
// const key = a[1].name;
// const value = a[1].level
// // img
// let actionId = key;
// let otf = 'Sk:"' + key + '"'; // This is going to end badly if the delimiter is set to ":"
// actions.push({
// id: actionId,
// name: coreModule.api.Utils.i18n(key) + " - test",
// description: coreModule.api.Utils.i18n('GURPS.Skills'),
// encodedValue: [macroType, otf].join(this.delimiter),
// })
// });
let skills = Object.entries(this.actor.system.skills) let skills = Object.entries(this.actor.system.skills)
// let map = this._get_contents(skills) skills.forEach((a) => {
let map = this._get_contents(skills, macroType) const key = a[1].name;
let names = Array.from(map.keys()).sort() const value = a[1].level
names.forEach((a)=> { // img
actions.push({
id: a,
name: map.get(a).name,
description: map.get(a).description,
encodedValue: map.get(a).encodedValue
})
})
let actionId = key;
let otf = 'Sk:"' + key + '"'; // This is going to end badly if the delimiter is set to ":"
actions.push({
id: actionId,
name: coreModule.api.Utils.i18n(key),
description: coreModule.api.Utils.i18n('GURPS.Skills'),
encodedValue: [macroType, otf].join(this.delimiter),
})
});
this.addActions(actions, parent) this.addActions(actions, parent)
} }
_get_contents(spells, macroType, result= new Map()) {
console.debug(spells);
console.debug(macroType);
console.debug(result)
if (spells instanceof Array) {
for (const spell in spells) {
let _contains = spells[spell][1].contains;
if (Reflect.has(_contains,"00000")) {
for( const i in _contains) {
result = this._get_contents(_contains[i], macroType, result)
}
}
else {
let name = spells[spell][1].name;
let level = spells[spell][1].level;
let otf_type = null;
if (macroType === "skills") {
otf_type = 'Sk'
}
else {
otf_type = 'Sp'
}
let otf = otf_type + ':"' + name + '"';
if (level) {
result.set(
name,
{
id: name,
name: coreModule.api.Utils.i18n(name),
description: coreModule.api.Utils.i18n('GURPS.Spells'),
encodedValue: [macroType, otf].join(this.delimiter),
}
)
}
}
}
}
else {
if (spells.uuid) {
let _contains = spells.contains;
if (Reflect.has(_contains,"00000")) {
for( const i in _contains) {
result = this._get_contents(_contains[i], macroType, result)
}
}
else {
let spell = spells;
let name = spell.name;
let level = spell.level;
let otf_type = null;
if (macroType === "skills") {
otf_type = 'Sk'
}
else {
otf_type = 'Sp'
}
let otf = otf_type + ':"' + name + '"';
if (level) {
result.set(
name,
{
id: name,
name: coreModule.api.Utils.i18n(name),
description: coreModule.api.Utils.i18n('GURPS.Spells'),
encodedValue: [macroType, otf].join(this.delimiter),
}
)
}
}
}
}
return result;
}
_get_spells(parent) { _get_spells(parent) {
// debugger;
const macroType = "spells"; const macroType = "spells";
let actions = []; let actions = [];
let spells = Object.entries(this.actor.system.spells)
let spell_map = this._get_contents(spells, macroType)
let spell_names = Array.from(spell_map.keys()).sort()
spell_names.forEach((a)=> {
actions.push({
id: a,
name: spell_map.get(a).name,
description: spell_map.get(a).description,
encodedValue: spell_map.get(a).encodedValue
})
})
let spells = Object.entries(this.actor.system.spells)
spells.forEach((a) => {
const key = a[1].name;
const value = a[1].level
// img
let actionId = key;
let otf = 'Sp:"' + key + '"'; // This is going to end badly if the delimiter is set to ":"
actions.push({
id: actionId,
name: coreModule.api.Utils.i18n(key),
description: coreModule.api.Utils.i18n('GURPS.Spells'),
encodedValue: [macroType, otf].join(this.delimiter),
})
});
this.addActions(actions, parent) this.addActions(actions, parent)
} }
@ -341,4 +256,3 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
} }
} }
}) })

View file

@ -29,7 +29,7 @@ export const ACTION_TYPE = {
* Groups * Groups
*/ */
// Note: names are automatically localized. I could have avoided some effort if I had realised that sooner. // Note: names are automatically localized. I could have avided some effort if I had realised that sooner.
export const GROUP = { export const GROUP = {
attributes: { id: 'attributes', name: 'GURPS.attributes', type: 'system' }, attributes: { id: 'attributes', name: 'GURPS.attributes', type: 'system' },

View file

@ -12,6 +12,7 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
group.listName = `Group: ${coreModule.api.Utils.i18n(group.listName ?? group.name)}` group.listName = `Group: ${coreModule.api.Utils.i18n(group.listName ?? group.name)}`
}) })
const groupsArray = Object.values(groups) const groupsArray = Object.values(groups)
// debugger;
DEFAULTS = { DEFAULTS = {
layout: [ layout: [
{ {

View file

@ -120,7 +120,7 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
case 'endTurn': case 'endTurn':
if (game.combat?.current?.tokenId === token.id) { if (game.combat?.current?.tokenId === token.id) {
await game.combat?.nextTurn() await game.combat?.nextTurn()
} }executeOTF
break break
} }
} }
@ -130,6 +130,7 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
if ( actionId == "WILL" ) actionId = "Will"; if ( actionId == "WILL" ) actionId = "Will";
if ( actionId == "PER" ) actionId = "Per"; if ( actionId == "PER" ) actionId = "Per";
// debugger;
let formula = '3d6'; let formula = '3d6';
let targetmods = null; let targetmods = null;
let prefix = "Rolls vs" // should be i18n of 'GURPS.rollVs' let prefix = "Rolls vs" // should be i18n of 'GURPS.rollVs'
@ -147,6 +148,8 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
async #handleMeleeAction(actor, actionId) { async #handleMeleeAction(actor, actionId) {
/* Melee attacks are done using the otf method. Grab the otf and pass it to the function. */ /* Melee attacks are done using the otf method. Grab the otf and pass it to the function. */
let GURPS = globalThis.GURPS; let GURPS = globalThis.GURPS;
// debugger;
let otf = actionId; let otf = actionId;
GURPS.executeOTF(otf, actor=actor); GURPS.executeOTF(otf, actor=actor);
} }
@ -154,22 +157,39 @@ Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => {
async #handleRangedAction(actor, actionId) { async #handleRangedAction(actor, actionId) {
/* Melee attacks are done using the otf method. Grab the otf and pass it to the function. */ /* Melee attacks are done using the otf method. Grab the otf and pass it to the function. */
let GURPS = globalThis.GURPS; let GURPS = globalThis.GURPS;
// debugger;
let otf = actionId; let otf = actionId;
GURPS.executeOTF(otf, actor=actor); GURPS.executeOTF(otf, actor=actor);
// doRoll({ actor, formula, targetmods, prefix, thing, chatthing, origtarget: target, optionalArgs: opt })
} }
async #handleSkillAction(actor, actionId) { async #handleSkillAction(actor, actionId) {
/* Skills are done using the otf method. Grab the otf and pass it to the function. */ /* Skills are done using the otf method. Grab the otf and pass it to the function. */
let GURPS = globalThis.GURPS; let GURPS = globalThis.GURPS;
// actor, formula, targetmods, prefix = '', thing = '', chatthing = '', origtarget = -1, optionalArgs = {},
// executeOTF(inputstring, priv = false, event = null, actor = null) {
// debugger;
let otf = actionId; let otf = actionId;
GURPS.executeOTF(otf, actor=actor); GURPS.executeOTF(otf, actor=actor);
// doRoll({ actor, formula, targetmods, prefix, thing, chatthing, origtarget: target, optionalArgs: opt })
} }
async #handleSpellAction(actor, actionId) { async #handleSpellAction(actor, actionId) {
/* Spells are done using the otf method. Grab the otf and pass it to the function. */ /* Spells are done using the otf method. Grab the otf and pass it to the function. */
let GURPS = globalThis.GURPS; let GURPS = globalThis.GURPS;
// debugger;
let otf = actionId; let otf = actionId;
GURPS.executeOTF(otf, actor=actor); GURPS.executeOTF(otf, actor=actor);
} }
} }
}) })