From cf95255a47c245c86c663cbcb2c155a65cdba1e8 Mon Sep 17 00:00:00 2001 From: BrotherSharper Date: Tue, 1 Jun 2021 21:01:11 +0900 Subject: [PATCH 01/14] ja.json update --- lang/ja.json | 56 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/lang/ja.json b/lang/ja.json index c66cf24..c8e0416 100644 --- a/lang/ja.json +++ b/lang/ja.json @@ -7,22 +7,19 @@ "MaterialDeck.Notifications.Playlist.NoPermission": "プレイリストを設定する権限がありません", "MaterialDeck.Sett.Enable": "モジュールの有効化", - "MaterialDeck.Sett.Model": "Stream Deck モデル", - "MaterialDeck.Sett.Model_Hint": "マクロとサウンドボードの設定画面でのマクロとサウンドの量を減らします。概要がわかりやすくなりますが、必要に応じてXLに設定して最大数を取得できます。これはモジュールの動作には影響しません。", - "MaterialDeck.Sett.Model_Mini": "Mini", - "MaterialDeck.Sett.Model_Normal": "Normal / Mobile", - "MaterialDeck.Sett.Model_XL": "XL", "MaterialDeck.Sett.Help": "ヘルプ", "MaterialDeck.Sett.Permission": "ユーザー権限の設定", "MaterialDeck.Sett.PlaylistConfig": "プレイリスト設定", "MaterialDeck.Sett.MacroConfig": "マクロ設定", "MaterialDeck.Sett.SoundboardConfig": "サウンド設定", "MaterialDeck.Sett.ServerAddr": "Material Server アドレス", - "MaterialDeck.Sett.ServerAddrHint": "MaterialServerのIPアドレスとポート。デフォルト値は99%の人に有効ですが、何をしているのかがわかっている場合にのみ変更してください。[ip_address]:[port]の形式に従う必要があります。例:「localhost:3001」または「192.168.1.1:4000」。", + "MaterialDeck.Sett.ServerAddrHint": "Material ServerのIPアドレスとポート。デフォルト値は99%の人に有効ですが、何をしているのかがわかっている場合にのみ変更してください。[ip_address]:[port]の形式に従う必要があります。例:「localhost:3001」または「192.168.1.1:4000」。", "MaterialDeck.Sett.ImageBuffer": "画像キャッシュサイズ", "MaterialDeck.Sett.ImageBufferHint": "画像キャッシュに保存する画像のデータ量を設定します。画像キャッシュは、ストリームデッキに送信されたすべての画像をローカルに保存します。これにより更新速度は向上しますが、メモリ使用量は増加します。", "MaterialDeck.Sett.ImageBrightness": "画像の明るさ", "MaterialDeck.Sett.ImageBrightnessHint": "デフォルトの画像の明るさを設定します。画像キャッシュサイズが0より大きい場合、更新を実行してください。", + "MaterialDeck.Sett.NrOfConnMessages": "接続警告回数", + "MaterialDeck.Sett.NrOfConnMessagesHint": "Material DeckがMaterial Serverに接続できない場合に表示される接続警告回数を設定します。0に設定すると、無制限となります。", "MaterialDeck.PL.Unrestricted": "無制限", "MaterialDeck.PL.OneTrackPlaylist": "プレイリストごとに1つのトラック", @@ -39,6 +36,8 @@ "MaterialDeck.Background": "背景", "MaterialDeck.Macro": "マクロ", "MaterialDeck.Sound": "サウンド", + "MaterialDeck.Sounds": "Sounds", + "MaterialDeck.Of": "of", "MaterialDeck.Icon": "アイコン", "MaterialDeck.Once": "一度だけ再生", "MaterialDeck.Repeat": "リピート再生", @@ -50,11 +49,28 @@ "MaterialDeck.Name": "名前", "MaterialDeck.None": "無し", "MaterialDeck.Save": "セーブ", + "MaterialDeck.ClearAll": "すべて クリア", + "MaterialDeck.ClearAll_Content": "すべてのデータがクリアされます。この操作は取り消すことができません、続行しますか?", + "MaterialDeck.ClearPage": "ページ クリア", + "MaterialDeck.ClearPage_Content": "このページのすべてのデータがクリアされます。この操作は取り消すことができません、続行しますか?", + "MaterialDeck.Continue": "継続", + "MaterialDeck.Cancel": "キャンセル", + "MaterialDeck.Import": "インポート", + "MaterialDeck.Export": "エクスポート", + "MaterialDeck.Filename": "ファイル名", + + "MaterialDeck.ExportDialog.Title": "エクスポート", + "MaterialDeck.ExportDialog.SoundboardContent": "SouseBoardデータをエクスポートします。メタデータのみがエクスポートされるので、インポートするときにオーディオファイルが相対的に同じ場所にあることを確認する必要があります。", + "MaterialDeck.ExportDialog.MacroboardContent": "MacroBoardデータをエクスポートします。メタデータのみがエクスポートされるため、インポートしたときに同じマクロが使用可能であることを確認する必要があります。", + + "MaterialDeck.ImportDialog.Title": "インポート", + "MaterialDeck.ImportDialog.SoundboardContent": "インポートするファイルを選択してください。メタデータのみがインポートされるので、オーディオファイルがそれらをエクスポートしたときと同じ相対的な場所にあることを確認する必要があります。", + "MaterialDeck.ImportDialog.MacroboardContent": "MacroBoardデータをインポートします。 ", + "MaterialDeck.ImportDialog.Warning": "現在の設定が上書きされ、元に戻すことはできません。", "MaterialDeck.FxMaster.Colorize": "色付け", "MaterialDeck.FxMaster.Clear": "すべてクリア", - "MaterialDeck.Perm.Instructions": "各Material Deckアクションの権限を設定します。", "MaterialDeck.Perm.DefaultNotification": "Material Deckのユーザー権限がデフォルト値に設定されています。", @@ -100,12 +116,6 @@ "MaterialDeck.Perm.MACRO.MACROBOARD_CONFIGURE.label": "マクロボードの設定", "MaterialDeck.Perm.MACRO.MACROBOARD_CONFIGURE.hint": "ユーザーがマクロボードを設定できるようにする。ユーザーがファイルエクスプローラを使用してアイコンを選択できるようにするには、コア設定の「権限の設定」でそのユーザーに対して「ファイルエクスプローラの使用」を有効にすること。", - "MaterialDeck.Perm.MOVE.label": "移動", - "MaterialDeck.Perm.MOVE.TOKEN.label": "トークン", - "MaterialDeck.Perm.MOVE.TOKEN.hint": "ユーザーが制御するトークンを移動できるようにする", - "MaterialDeck.Perm.MOVE.CANVAS.label": "キャンバス", - "MaterialDeck.Perm.MOVE.CANVAS.hint": "ユーザーがキャンバスを移動できるようにする", - "MaterialDeck.Perm.OTHER.label": "その他", "MaterialDeck.Perm.OTHER.PAUSE.label": "一時停止/再開", "MaterialDeck.Perm.OTHER.PAUSE.hint": "ユーザーがゲームを一時停止または再開できるようにする", @@ -178,6 +188,22 @@ "MaterialDeck.AboutTime.Second": "2", "MaterialDeck.AboutTime.Third": "3", "MaterialDeck.AboutTime.Fourth": "4", - "MaterialDeck.AboutTime.Of": "/" -} + "MaterialDeck.AboutTime.Of": "/", + "MaterialDeck.DownloadUtility.Title": "ダウンロード・ユーティリティ", + "MaterialDeck.DownloadUtility.Plugin": "プラグイン&Material Server", + "MaterialDeck.DownloadUtility.Minimum": "最小", + "MaterialDeck.DownloadUtility.Current": "現在", + "MaterialDeck.DownloadUtility.Latest": "最新", + "MaterialDeck.DownloadUtility.OS": "OS", + "MaterialDeck.DownloadUtility.Download": "ダウンロード", + "MaterialDeck.DownloadUtility.SDplugin": "SDプラグイン", + "MaterialDeck.DownloadUtility.MSserver": "Material Server", + "MaterialDeck.DownloadUtility.Windows": "Windows", + "MaterialDeck.DownloadUtility.Macos": "MacOS", + "MaterialDeck.DownloadUtility.Linux": "Linux", + "MaterialDeck.DownloadUtility.Source": "ソース", + "MaterialDeck.DownloadUtility.Profiles": "プロファイル", + "MaterialDeck.DownloadUtility.Name": "名前", + "MaterialDeck.DownloadUtility.Refresh": "更新" +} \ No newline at end of file From efbbdf77605bcb84bf3140d181856cb7319b095b Mon Sep 17 00:00:00 2001 From: Lyle hayhurst Date: Tue, 1 Jun 2021 19:57:44 -0500 Subject: [PATCH 02/14] WIP comit with @solo --- MaterialDeck.js | 2 +- src/systems/tokenHelper.js | 2 + src/systems/wfrp4.js | 119 +++++++++++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 src/systems/wfrp4.js diff --git a/MaterialDeck.js b/MaterialDeck.js index bd9c508..86e1eb3 100644 --- a/MaterialDeck.js +++ b/MaterialDeck.js @@ -390,7 +390,7 @@ Hooks.on('updateToken',(scene,token)=>{ if (macroControl != undefined) macroControl.updateAll(); }); -Hooks.on('updateActor',(scene,actor)=>{ +Hooks.on('updateActor',(actor)=>{ if (enableModule == false || ready == false) return; let children = canvas.tokens.children[0].children; for (let i=0; i e.id === condition); + await token.toggleEffect(effect); + } + return true; + } + + /** + * Roll + */ + roll(token,roll,options,ability,skill,save) { + return; + } + + /** + * Items + */ + getItems(token,itemType) { + if (itemType == undefined) itemType = 'any'; + const allItems = token.actor.items; + if (itemType == 'any') return allItems.filter(i => i.type == 'item'); + } + + getItemUses(item) { + return {available: item.data.data.quantity}; + } + + /** + * Spells + */ + getSpells(token,level) { + return; + } + + getSpellUses(token,level,item) { + return; + } +} \ No newline at end of file From 63bda666b52a218e61df4c1b84934c4a21b1e321 Mon Sep 17 00:00:00 2001 From: Lyle hayhurst Date: Wed, 2 Jun 2021 08:15:04 -0500 Subject: [PATCH 03/14] renamed to wfrp4e --- src/systems/tokenHelper.js | 4 ++-- src/systems/{wfrp4.js => wfrp4e.js} | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/systems/{wfrp4.js => wfrp4e.js} (96%) diff --git a/src/systems/tokenHelper.js b/src/systems/tokenHelper.js index 18ee7e3..4217aa2 100644 --- a/src/systems/tokenHelper.js +++ b/src/systems/tokenHelper.js @@ -2,7 +2,7 @@ import {dnd5e} from "./dnd5e.js" import {dnd35e} from "./dnd35e.js" import {pf2e} from "./pf2e.js" import {demonlord} from "./demonlord.js"; -import {wfrp4} from "./wfrp4.js" +import {wfrp4e} from "./wfrp4e.js" import {compatibleCore} from "../misc.js"; export class TokenHelper{ @@ -15,7 +15,7 @@ export class TokenHelper{ if (game.system.id == 'D35E' || game.system.id == 'pf1') this.system = new dnd35e(); else if (game.system.id == 'pf2e') this.system = new pf2e(); else if (game.system.id == 'demonlord') this.system = new demonlord(); - else if (game.system.id == 'wfrp4') this.system = new wfrp4(); + else if (game.system.id == 'wfrp4e') this.system = new wfrp4e(); else this.system = new dnd5e(); //default to dnd5e } diff --git a/src/systems/wfrp4.js b/src/systems/wfrp4e.js similarity index 96% rename from src/systems/wfrp4.js rename to src/systems/wfrp4e.js index 8f5da10..e5603fb 100644 --- a/src/systems/wfrp4.js +++ b/src/systems/wfrp4e.js @@ -1,6 +1,6 @@ import {compatibleCore} from "../misc.js"; -export class wfrp4{ +export class wfrp4e { constructor(){ } @@ -26,7 +26,7 @@ export class wfrp4{ } getSpeed(token) { - return; + return token.actor.data.data.details.move.value; } getInitiative(token) { From 87a031ae44bc99c9bc149ff2063b2891e117f313 Mon Sep 17 00:00:00 2001 From: Lyle hayhurst Date: Wed, 2 Jun 2021 23:50:12 -0500 Subject: [PATCH 04/14] added support for fate and wounds. --- DEVGUIDE.md | 37 +++++++++++++++++++++++++++++++++++++ README.md | 3 +++ src/systems/tokenHelper.js | 6 ++++++ src/systems/wfrp4e.js | 11 ++++++++++- src/token.js | 4 +++- 5 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 DEVGUIDE.md diff --git a/DEVGUIDE.md b/DEVGUIDE.md new file mode 100644 index 0000000..b659749 --- /dev/null +++ b/DEVGUIDE.md @@ -0,0 +1,37 @@ + +# Dev Guide + + +## Module Development + +### Make a new system.js file + +In the [src/systems](src/systems) directory, create a new system file by copying and pasting a similar system to it; for example, `cp demonlord.js wfrp4.js` +You then need to go through all the functions in there and make sure that the correct data is set. + +### Update TokenHelper +In [src/systems/TokenHelper.js](src/systems/TokenHelper.js), you need to add an `import {}` for your new system. + +In the same file, in the setSystem() function, you need to wire in your system to the if/else block. + +## Debugging + +It's possible to debug on the Stream Deck, so you can do `console.log`. Just follow the instructions [from elgato here](https://developer.elgato.com/documentation/stream-deck/sdk/create-your-own-plugin/). After editing the code for the plugin, you need to either refresh by refreshing the debug window, or by deselecting the current button, and selecting it again. + +## + +For getStats, getRolls you cannot change value + +For the others, it depends on the system. For example: +in 5e, to get the appraise skill modifier, you do token.actor.data.data.skills?.[skill].total where 'skill' is 'apr'. So in the plugin, you have to set the value to 'apr'. + +## Streamdeck + +On the SD side: The plugin in windows is located at AppData/Roaming/Elgato/StreamDeck/Plugins/com.cdeenen.materialdeck.sdPlugin +In propertyinspector/js/common.js starting at line 1274 there's various functions that are used to get the relevant options to show up in the SD plugin. Each array element has a value and a name, you should keep the value the same, but the name can be whatever you like. I think you'll be able to figure out how to add stuff for wfrp by looking at the others. + +To enable logging on the streamdeck, [follow these instructions](https://developer.elgato.com/documentation/stream-deck/sdk/create-your-own-plugin/) from Elgato. + + +## Module Deployment +Copy the new system.js and tokenHelper.js \ No newline at end of file diff --git a/README.md b/README.md index a0fdde6..1af3cf2 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,9 @@ Module manifest: https://raw.githubusercontent.com/CDeenen/MaterialDeck/Master/m Foundry VTT: Tested on 0.7.9 - 0.8.5
Module Incompatibilities: None known.
+## Developer Guide +See the [developer guide](./DEVGUIDE.md) for a guide on how to add new systems to `MaterialDeck`. + ## Feedback If you have any suggestions or bugs to report, feel free to create an issue, contact me on Discord (Cris#6864), or send me an email: cdeenen@outlook.com. diff --git a/src/systems/tokenHelper.js b/src/systems/tokenHelper.js index 4217aa2..c7008a8 100644 --- a/src/systems/tokenHelper.js +++ b/src/systems/tokenHelper.js @@ -186,6 +186,12 @@ export class TokenHelper{ return this.system.getProficiency(token); } + /* WFRP 4E */ + getFate(token) { + return this.system.getFate(token) + } + + /** * Conditions */ diff --git a/src/systems/wfrp4e.js b/src/systems/wfrp4e.js index e5603fb..8216a91 100644 --- a/src/systems/wfrp4e.js +++ b/src/systems/wfrp4e.js @@ -5,12 +5,21 @@ export class wfrp4e { } - getHP(token) { + getFate(token) { + return token.actor.data.data.status.fate.value + } + + getWounds(token) { const wounds = token.actor.data.data.status.wounds return { value: wounds.value, max: wounds.max } + + } + + getHP(token) { + return this.getWounds(token); } getTempHP(token) { diff --git a/src/token.js b/src/token.js index 36efe9b..2c2a4f3 100644 --- a/src/token.js +++ b/src/token.js @@ -94,7 +94,7 @@ export class TokenControl{ } } - if (stats == 'HP') { + if (stats == 'HP' || stats == 'Wounds') { const hp = tokenHelper.getHP(token); txt += hp.value + "/" + hp.max; @@ -135,6 +135,8 @@ export class TokenControl{ else if (stats == 'Save') txt += tokenHelper.getAbilitySave(token, settings.save); else if (stats == 'Skill') txt += tokenHelper.getSkill(token, settings.skill); else if (stats == 'Prof') txt += tokenHelper.getProficiency(token); + else if (stats == 'Fate') txt += tokenHelper.getFate(token) + if (settings.onClick == 'visibility') { //toggle visibility if (MODULE.getPermission('TOKEN','VISIBILITY') == false ) { From 2dcbfbe0964885665a8af40f71bba414bdf943ba Mon Sep 17 00:00:00 2001 From: Lyle hayhurst Date: Thu, 3 Jun 2021 08:42:08 -0500 Subject: [PATCH 05/14] added basics of getItems() --- src/systems/wfrp4e.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/systems/wfrp4e.js b/src/systems/wfrp4e.js index 8216a91..65d32fa 100644 --- a/src/systems/wfrp4e.js +++ b/src/systems/wfrp4e.js @@ -106,9 +106,13 @@ export class wfrp4e { * Items */ getItems(token,itemType) { + if (itemType == undefined) itemType = 'any'; const allItems = token.actor.items; - if (itemType == 'any') return allItems.filter(i => i.type == 'item'); + console.log("allitems: "+ allItems); + if (itemType == 'any') return allItems.filter(i => i.type == "weapon" || + i.type == "armour" || + i.type == "ammunition" ); // i.type == 'item'); } getItemUses(item) { From 9ffa796eeb8c8be1bca9f750a481cbef5615d3cd Mon Sep 17 00:00:00 2001 From: Lyle hayhurst Date: Fri, 4 Jun 2021 08:14:28 -0500 Subject: [PATCH 06/14] added item types --- DEVGUIDE.md | 13 ++++++++++--- MaterialDeck.js | 2 +- src/systems/wfrp4e.js | 19 +++++++++++++++---- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/DEVGUIDE.md b/DEVGUIDE.md index b659749..ea1d21a 100644 --- a/DEVGUIDE.md +++ b/DEVGUIDE.md @@ -1,6 +1,7 @@ # Dev Guide +In addition to this repo, you will also need to check out the [MaterialDeck_SD github repo](https://github.com/CDeenen/MaterialDeck_SD). ## Module Development @@ -18,7 +19,10 @@ In the same file, in the setSystem() function, you need to wire in your system t It's possible to debug on the Stream Deck, so you can do `console.log`. Just follow the instructions [from elgato here](https://developer.elgato.com/documentation/stream-deck/sdk/create-your-own-plugin/). After editing the code for the plugin, you need to either refresh by refreshing the debug window, or by deselecting the current button, and selecting it again. -## +When you go to the debugging page, there should be multiple options. With the property inspector open, you should connect to the one with property inspector in its name. If you go to to propertyinspector/js/common.js, near the top there's the debugEn variable. Set it to true, and you should get tons of messages, especially if you change any settings. +In the module, in MaterialDeck.js, at line 60, there's //console.log("Received",data);. If you uncomment that, it'll log everything that's send from the SD to the module. Might be helpful for debugging. + +## Verify the below For getStats, getRolls you cannot change value @@ -26,12 +30,15 @@ For the others, it depends on the system. For example: in 5e, to get the appraise skill modifier, you do token.actor.data.data.skills?.[skill].total where 'skill' is 'apr'. So in the plugin, you have to set the value to 'apr'. ## Streamdeck - On the SD side: The plugin in windows is located at AppData/Roaming/Elgato/StreamDeck/Plugins/com.cdeenen.materialdeck.sdPlugin In propertyinspector/js/common.js starting at line 1274 there's various functions that are used to get the relevant options to show up in the SD plugin. Each array element has a value and a name, you should keep the value the same, but the name can be whatever you like. I think you'll be able to figure out how to add stuff for wfrp by looking at the others. To enable logging on the streamdeck, [follow these instructions](https://developer.elgato.com/documentation/stream-deck/sdk/create-your-own-plugin/) from Elgato. +## Property discovery +In a Foundry client browser instance, if you go to the dev console, you can browser your tokens via the `canvas.tokens` path, for exmaple `canvas.tokens.children[0].children[0].actor.items`. ## Module Deployment -Copy the new system.js and tokenHelper.js \ No newline at end of file +If you make changes to files in this project, you'll need to copy the changed files to your Foundry install folder, probably found here: `C:\Users\$USER\AppData\Local\FoundryVTT\Data\modules\MaterialDeck`. + +If you change the `MaterialDeck_SD` code (for example, `propertyinspector\js\common.js`), you will need to copy that file to the Elgato streamdeck plugins directory, probably found here: `C:\Users\$USER\AppData\Roaming\Elgato\StreamDeck\Plugins\com.cdeenen.materialdeck.sdPlugin`. \ No newline at end of file diff --git a/MaterialDeck.js b/MaterialDeck.js index 86e1eb3..7558006 100644 --- a/MaterialDeck.js +++ b/MaterialDeck.js @@ -57,7 +57,7 @@ let WSconnected = false; async function analyzeWSmessage(msg){ if (enableModule == false) return; const data = JSON.parse(msg); - //console.log("Received",data); + console.log("Received",data); if (data.type == "connected" && data.data == "SD"){ const msg = { diff --git a/src/systems/wfrp4e.js b/src/systems/wfrp4e.js index 65d32fa..92512e5 100644 --- a/src/systems/wfrp4e.js +++ b/src/systems/wfrp4e.js @@ -104,17 +104,28 @@ export class wfrp4e { /** * Items - */ + getItems(token,itemType) { if (itemType == undefined) itemType = 'any'; const allItems = token.actor.items; console.log("allitems: "+ allItems); - if (itemType == 'any') return allItems.filter(i => i.type == "weapon" || - i.type == "armour" || - i.type == "ammunition" ); // i.type == 'item'); + if (itemType == 'any') return allItems.filter(i => i.type == itemType); + } */ + + getItems(token,itemType) { + if (itemType == undefined) itemType = 'any'; + const allItems = token.actor.items; + if (itemType == 'any') return allItems.filter(i => i.type == 'weapon' || + i.type == 'ammunition' || + i.type == 'armour' || + i.type == 'trapping'); + else { + return allItems.filter(i => i.type == itemType); + } } + getItemUses(item) { return {available: item.data.data.quantity}; } From ec207fa658cdd82500c498dae9eb8494cf0efd95 Mon Sep 17 00:00:00 2001 From: Lyle hayhurst Date: Fri, 4 Jun 2021 09:02:52 -0500 Subject: [PATCH 07/14] added item display, item rolling --- MaterialDeck.js | 2 +- src/systems/wfrp4e.js | 8 +++++++- src/token.js | 10 +++++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/MaterialDeck.js b/MaterialDeck.js index 7558006..7e5ea67 100644 --- a/MaterialDeck.js +++ b/MaterialDeck.js @@ -57,7 +57,7 @@ let WSconnected = false; async function analyzeWSmessage(msg){ if (enableModule == false) return; const data = JSON.parse(msg); - console.log("Received",data); +// console.log("Received",data); if (data.type == "connected" && data.data == "SD"){ const msg = { diff --git a/src/systems/wfrp4e.js b/src/systems/wfrp4e.js index 92512e5..55626fc 100644 --- a/src/systems/wfrp4e.js +++ b/src/systems/wfrp4e.js @@ -127,7 +127,13 @@ export class wfrp4e { getItemUses(item) { - return {available: item.data.data.quantity}; + console.log("getItemUses(" , item , ")") + if ( item.type == 'ammunition') { + return {available: item.data.data.quantity.value}; + } + else { + return {}; + } } /** diff --git a/src/token.js b/src/token.js index 2c2a4f3..91655bb 100644 --- a/src/token.js +++ b/src/token.js @@ -741,7 +741,15 @@ export class TokenControl{ items = this.sortItems(items); const item = items[itemNr]; - if (item != undefined) item.roll(); + if (item != undefined) { + if (game.system.id == 'wfrp4e') { + console.log("rolling wfrp4e item macro") + game.wfrp4e.utility.rollItemMacro(item.name, item.type, false); + } + else { + item.roll(); + } + } } } From cffa2318f757fae816135fbbffe38e5a41742747 Mon Sep 17 00:00:00 2001 From: Lyle hayhurst Date: Sun, 6 Jun 2021 08:54:47 -0500 Subject: [PATCH 08/14] better return type. --- src/systems/wfrp4e.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/systems/wfrp4e.js b/src/systems/wfrp4e.js index 55626fc..3152290 100644 --- a/src/systems/wfrp4e.js +++ b/src/systems/wfrp4e.js @@ -132,7 +132,7 @@ export class wfrp4e { return {available: item.data.data.quantity.value}; } else { - return {}; + return; } } From 560c3a573f57ec0dfb762376180587d3b7e10130 Mon Sep 17 00:00:00 2001 From: Lyle hayhurst Date: Sun, 6 Jun 2021 09:23:47 -0500 Subject: [PATCH 09/14] Added rollItem() family of methods --- src/systems/demonlord.js | 4 ++++ src/systems/dnd35e.js | 4 ++++ src/systems/dnd5e.js | 4 ++++ src/systems/pf2e.js | 4 ++++ src/systems/tokenHelper.js | 4 ++++ src/token.js | 4 +++- 6 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/systems/demonlord.js b/src/systems/demonlord.js index ad8cd53..2cabe4a 100644 --- a/src/systems/demonlord.js +++ b/src/systems/demonlord.js @@ -130,4 +130,8 @@ export class demonlord{ getSpellUses(token,level,item) { return; } + + rollItem(item) { + return item.roll() + } } \ No newline at end of file diff --git a/src/systems/dnd35e.js b/src/systems/dnd35e.js index 10eb4cc..32d1604 100644 --- a/src/systems/dnd35e.js +++ b/src/systems/dnd35e.js @@ -195,4 +195,8 @@ export class dnd35e{ maximum: item.maxCharges } } + + rollItem(item) { + return item.roll() + } } \ No newline at end of file diff --git a/src/systems/dnd5e.js b/src/systems/dnd5e.js index 20844c0..b32ee24 100644 --- a/src/systems/dnd5e.js +++ b/src/systems/dnd5e.js @@ -198,4 +198,8 @@ export class dnd5e{ maximum: token.actor.data.data.spells?.[`spell${level}`].max } } + + rollItem(item) { + return item.roll() + } } \ No newline at end of file diff --git a/src/systems/pf2e.js b/src/systems/pf2e.js index f4798af..21ee59f 100644 --- a/src/systems/pf2e.js +++ b/src/systems/pf2e.js @@ -192,4 +192,8 @@ export class pf2e{ maximum: spellbook.data.data.slots?.[`slot${level}`].max } } + + rollItem(item) { + return item.roll() + } } \ No newline at end of file diff --git a/src/systems/tokenHelper.js b/src/systems/tokenHelper.js index 4198a05..f777fcb 100644 --- a/src/systems/tokenHelper.js +++ b/src/systems/tokenHelper.js @@ -238,4 +238,8 @@ export class TokenHelper{ getSpellUses(token,level,item) { return this.system.getSpellUses(token,level,item); } + + rollItem(item) { + return this.system.rollItem(item); + } } \ No newline at end of file diff --git a/src/token.js b/src/token.js index 36efe9b..132b473 100644 --- a/src/token.js +++ b/src/token.js @@ -739,7 +739,9 @@ export class TokenControl{ items = this.sortItems(items); const item = items[itemNr]; - if (item != undefined) item.roll(); + if (item != undefined) { + tokenHelper.rollItem(item); + } } } From 5c6a4a4223677e20bb4112d628b818be954394eb Mon Sep 17 00:00:00 2001 From: Lyle hayhurst Date: Sun, 6 Jun 2021 11:14:25 -0500 Subject: [PATCH 10/14] add impl of rollitem --- src/systems/wfrp4e.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/systems/wfrp4e.js b/src/systems/wfrp4e.js index 3152290..e44a8cf 100644 --- a/src/systems/wfrp4e.js +++ b/src/systems/wfrp4e.js @@ -22,6 +22,10 @@ export class wfrp4e { return this.getWounds(token); } + rollItem(item) { + return Gamepad.wfrp4e.utility.rollItemMacro(item.name, item.type, false); + } + getTempHP(token) { return; } From 9e12b7cd84f642e5b1c5c85be935659200f2217d Mon Sep 17 00:00:00 2001 From: Lyle hayhurst Date: Sun, 6 Jun 2021 11:18:35 -0500 Subject: [PATCH 11/14] fix item roll --- src/systems/wfrp4e.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/systems/wfrp4e.js b/src/systems/wfrp4e.js index e44a8cf..c024b33 100644 --- a/src/systems/wfrp4e.js +++ b/src/systems/wfrp4e.js @@ -23,7 +23,7 @@ export class wfrp4e { } rollItem(item) { - return Gamepad.wfrp4e.utility.rollItemMacro(item.name, item.type, false); + return game.wfrp4e.utility.rollItemMacro(item.name, item.type, false); } getTempHP(token) { From b4fe33782405b807617e38fec2f3e3da50f04e42 Mon Sep 17 00:00:00 2001 From: Lyle hayhurst Date: Mon, 7 Jun 2021 15:21:35 -0500 Subject: [PATCH 12/14] Added characteristics with @cdeendan and @echobold --- src/systems/wfrp4e.js | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/src/systems/wfrp4e.js b/src/systems/wfrp4e.js index c024b33..d33e3bd 100644 --- a/src/systems/wfrp4e.js +++ b/src/systems/wfrp4e.js @@ -18,6 +18,27 @@ export class wfrp4e { } + + getAbility(token, abilityName) { + return this.getCharacteristics(token, abilityName); + } + + getCharacteristics(token, characteristicName) { + console.log("getCharacteristics(", token, ", ", characteristicName); // TODO: feature-wfrp4 remove + if (characteristicName == undefined ) characteristicName = `AG`; + const characteristic = token.actor.data.data.characteristics[characteristicName.toLowerCase()] + console.log(characteristic); + const val = characteristic.value; + return (val >= 0) ? `+${val}` : val; + } + + getFeatures(token,featureType) { + if (featureType == undefined) featureType = 'any'; + const allItems = token.actor.items; + if (featureType == 'any') return allItems.filter(i => i.type == 'skill' || i.type == 'talent' || i.type == "career" || i.type == 'trait'); + else return allItems.filter(i => i.type == featureType); + } + getHP(token) { return this.getWounds(token); } @@ -58,10 +79,6 @@ export class wfrp4e { return; } - getAbility(token, ability) { - return; - } - getAbilityModifier(token, ability) { return; } @@ -103,7 +120,18 @@ export class wfrp4e { * Roll */ roll(token,roll,options,ability,skill,save) { - return; + console.log("roll(", token, roll, options, ability, skill, save, ")"); + // if (roll == undefined) roll = 'ability'; + if (ability == undefined) ability = 'ag'; + // if (skill == undefined) skill = 'acr'; + // if (save == undefined) save = 'str'; + + // if (roll == 'ability') token.actor.rollAbilityTest(ability,options); + // else if (roll == 'save') token.actor.rollAbilitySave(save,options); + // else if (roll == 'skill') token.actor.rollSkill(skill,options); + // else if (roll == 'initiative') token.actor.rollInitiative(options); + // else if (roll == 'deathSave') token.actor.rollDeathSave(options); + return game.wfrp4e.utility.rollItemMacro(ability, "characteristic", false); } /** From a5655f46dde5b12041170c51496d1383e3ea3f15 Mon Sep 17 00:00:00 2001 From: Lyle hayhurst Date: Mon, 7 Jun 2021 19:44:36 -0500 Subject: [PATCH 13/14] getting skill bonuses showing --- DEVGUIDE.md | 2 +- src/systems/wfrp4e.js | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/DEVGUIDE.md b/DEVGUIDE.md index ea1d21a..643b04b 100644 --- a/DEVGUIDE.md +++ b/DEVGUIDE.md @@ -36,7 +36,7 @@ In propertyinspector/js/common.js starting at line 1274 there's various function To enable logging on the streamdeck, [follow these instructions](https://developer.elgato.com/documentation/stream-deck/sdk/create-your-own-plugin/) from Elgato. ## Property discovery -In a Foundry client browser instance, if you go to the dev console, you can browser your tokens via the `canvas.tokens` path, for exmaple `canvas.tokens.children[0].children[0].actor.items`. +In a Foundry client browser instance, if you go to the dev console, you can browser your tokens via the `canvas.tokens` path, for example `canvas.tokens.children[0].children[0].actor.data`. ## Module Deployment If you make changes to files in this project, you'll need to copy the changed files to your Foundry install folder, probably found here: `C:\Users\$USER\AppData\Local\FoundryVTT\Data\modules\MaterialDeck`. diff --git a/src/systems/wfrp4e.js b/src/systems/wfrp4e.js index d33e3bd..84b03cb 100644 --- a/src/systems/wfrp4e.js +++ b/src/systems/wfrp4e.js @@ -35,8 +35,13 @@ export class wfrp4e { getFeatures(token,featureType) { if (featureType == undefined) featureType = 'any'; const allItems = token.actor.items; + console.log(allItems); if (featureType == 'any') return allItems.filter(i => i.type == 'skill' || i.type == 'talent' || i.type == "career" || i.type == 'trait'); - else return allItems.filter(i => i.type == featureType); + return allItems.filter(i => i.type == featureType); + } + + getFeatureUses(item) { + return {available: `+${item.data.data.total.value}`}; } getHP(token) { From 26afbae66b0a1d7cbf92a14b35d7d64abc6e5db3 Mon Sep 17 00:00:00 2001 From: Lyle hayhurst Date: Sun, 20 Jun 2021 00:03:44 -0500 Subject: [PATCH 14/14] Final bits. with @solo --- DEVGUIDE.md | 12 +-- README.md | 1 + src/systems/tokenHelper.js | 29 +++++++ src/systems/wfrp4e.js | 150 +++++++++++++++++-------------------- src/token.js | 19 ++++- 5 files changed, 120 insertions(+), 91 deletions(-) diff --git a/DEVGUIDE.md b/DEVGUIDE.md index 643b04b..cc1f038 100644 --- a/DEVGUIDE.md +++ b/DEVGUIDE.md @@ -22,19 +22,15 @@ It's possible to debug on the Stream Deck, so you can do `console.log`. Just fol When you go to the debugging page, there should be multiple options. With the property inspector open, you should connect to the one with property inspector in its name. If you go to to propertyinspector/js/common.js, near the top there's the debugEn variable. Set it to true, and you should get tons of messages, especially if you change any settings. In the module, in MaterialDeck.js, at line 60, there's //console.log("Received",data);. If you uncomment that, it'll log everything that's send from the SD to the module. Might be helpful for debugging. -## Verify the below - -For getStats, getRolls you cannot change value - -For the others, it depends on the system. For example: -in 5e, to get the appraise skill modifier, you do token.actor.data.data.skills?.[skill].total where 'skill' is 'apr'. So in the plugin, you have to set the value to 'apr'. ## Streamdeck -On the SD side: The plugin in windows is located at AppData/Roaming/Elgato/StreamDeck/Plugins/com.cdeenen.materialdeck.sdPlugin -In propertyinspector/js/common.js starting at line 1274 there's various functions that are used to get the relevant options to show up in the SD plugin. Each array element has a value and a name, you should keep the value the same, but the name can be whatever you like. I think you'll be able to figure out how to add stuff for wfrp by looking at the others. To enable logging on the streamdeck, [follow these instructions](https://developer.elgato.com/documentation/stream-deck/sdk/create-your-own-plugin/) from Elgato. +The plugin in Windows is located at (Windows) `AppData/Roaming/Elgato/StreamDeck/Plugins/com.cdeenen.materialdeck.sdPlugin` +In `propertyinspector/js/common.js::getStats()` there are various functions that are used to get the relevant options to show up in the SD plugin. Each array element has a value and a name, you should keep the value the same, but the name can be whatever you like. I think you'll be able to figure out how to add stuff for wfrp by looking at the others. + + ## Property discovery In a Foundry client browser instance, if you go to the dev console, you can browser your tokens via the `canvas.tokens` path, for example `canvas.tokens.children[0].children[0].actor.data`. diff --git a/README.md b/README.md index 1af3cf2..931e2b8 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ Special thanks to Asmodeus#7588 who made this module possible by generously dona
Please consider supporting me on Patreon, and feel free to join the Material Foundry Discord server. + ## Abandonment Abandoned modules are a (potential) problem for Foundry, because users and/or other modules might rely on abandoned modules, which might break in future Foundry updates.
I consider this module abandoned if all of the below cases apply: diff --git a/src/systems/tokenHelper.js b/src/systems/tokenHelper.js index 47e0cb1..aad53eb 100644 --- a/src/systems/tokenHelper.js +++ b/src/systems/tokenHelper.js @@ -191,6 +191,35 @@ export class TokenHelper{ return this.system.getFate(token) } + /* WFRP 4E */ + getFortune(token) { + return this.system.getFortune(token) + } + + /* WFRP 4E */ + getCriticalWounds(token) { + return this.system.getCriticalWounds(token) + } + + /* WFRP 4E */ + getCorruption(token) { + return this.system.getCorruption(token) + } + + /* WFRP 4E */ + getAdvantage(token) { + return this.system.getAdvantage(token) + } + + /* WFRP 4E */ + getResolve(token) { + return this.system.getResolve(token) + } + + /* WFRP 4E */ + getResilience(token) { + return this.system.getResilience(token) + } /** * Conditions diff --git a/src/systems/wfrp4e.js b/src/systems/wfrp4e.js index 84b03cb..6588b2f 100644 --- a/src/systems/wfrp4e.js +++ b/src/systems/wfrp4e.js @@ -9,6 +9,11 @@ export class wfrp4e { return token.actor.data.data.status.fate.value } + getFortune(token) { + return token.actor.data.data.status.fortune.value + } + + getWounds(token) { const wounds = token.actor.data.data.status.wounds return { @@ -18,16 +23,37 @@ export class wfrp4e { } + getCriticalWounds(token) { + const criticalWounds = token.actor.data.data.status.criticalWounds + return { + value: criticalWounds.value, + max: criticalWounds.max + } + } + + getCorruption(token) { + return token.actor.data.data.status.corruption.value + } + + getAdvantage(token) { + return token.actor.data.data.status.advantage.value + } + + getResolve(token) { + return token.actor.data.data.status.resolve.value + } + + getResilience(token) { + return token.actor.data.data.status.resilience.value + } getAbility(token, abilityName) { return this.getCharacteristics(token, abilityName); } getCharacteristics(token, characteristicName) { - console.log("getCharacteristics(", token, ", ", characteristicName); // TODO: feature-wfrp4 remove if (characteristicName == undefined ) characteristicName = `AG`; const characteristic = token.actor.data.data.characteristics[characteristicName.toLowerCase()] - console.log(characteristic); const val = characteristic.value; return (val >= 0) ? `+${val}` : val; } @@ -35,10 +61,17 @@ export class wfrp4e { getFeatures(token,featureType) { if (featureType == undefined) featureType = 'any'; const allItems = token.actor.items; - console.log(allItems); if (featureType == 'any') return allItems.filter(i => i.type == 'skill' || i.type == 'talent' || i.type == "career" || i.type == 'trait'); return allItems.filter(i => i.type == featureType); } + getSpells(token,spellType) { + const allItems = token.actor.items; + return allItems.filter(i => i.type == 'spell') + } + + getSpellUses(token,level,item) { + return; + } getFeatureUses(item) { return {available: `+${item.data.data.total.value}`}; @@ -52,61 +85,10 @@ export class wfrp4e { return game.wfrp4e.utility.rollItemMacro(item.name, item.type, false); } - getTempHP(token) { - return; - } - - getAC(token) { - return; - } - - getShieldHP(token) { - return; - } - getSpeed(token) { return token.actor.data.data.details.move.value; } - getInitiative(token) { - return; - } - - toggleInitiative(token) { - return; - } - - getPassivePerception(token) { - return; - } - - getPassiveInvestigation(token) { - return; - } - - getAbilityModifier(token, ability) { - return; - } - - getAbilitySave(token, ability) { - return; - } - - getSkill(token, skill) { - return; - } - - getProficiency(token) { - return; - } - - getConditionIcon(condition) { - return; - } - - getConditionActive(token,condition) { - return; - } async toggleCondition(token,condition) { if (condition == undefined) condition = 'removeAll'; @@ -121,34 +103,13 @@ export class wfrp4e { return true; } - /** - * Roll - */ - roll(token,roll,options,ability,skill,save) { - console.log("roll(", token, roll, options, ability, skill, save, ")"); - // if (roll == undefined) roll = 'ability'; + roll(token,roll,options,ability,skill,save) { + //console.log("roll(", token, roll, options, ability, skill, save, ")"); if (ability == undefined) ability = 'ag'; - // if (skill == undefined) skill = 'acr'; - // if (save == undefined) save = 'str'; - - // if (roll == 'ability') token.actor.rollAbilityTest(ability,options); - // else if (roll == 'save') token.actor.rollAbilitySave(save,options); - // else if (roll == 'skill') token.actor.rollSkill(skill,options); - // else if (roll == 'initiative') token.actor.rollInitiative(options); - // else if (roll == 'deathSave') token.actor.rollDeathSave(options); return game.wfrp4e.utility.rollItemMacro(ability, "characteristic", false); } - /** - * Items - - getItems(token,itemType) { - if (itemType == undefined) itemType = 'any'; - const allItems = token.actor.items; - console.log("allitems: "+ allItems); - if (itemType == 'any') return allItems.filter(i => i.type == itemType); - } */ getItems(token,itemType) { if (itemType == undefined) itemType = 'any'; @@ -173,14 +134,39 @@ export class wfrp4e { } } - /** - * Spells - */ - getSpells(token,level) { + + /* this is all cargo-culted in and some of it could be deleted once the interface is resolved + to not be the superset of all possible systems + */ + + getAC(token) { return; } - getSpellUses(token,level,item) { + getShieldHP(token) { return; } + + getInitiative(token) { + return; + } + + toggleInitiative(token) { + return; + } + + + getConditionIcon(condition) { + return; + } + + getConditionActive(token,condition) { + return; + } + + getTempHP(token) { + return; + } + + } \ No newline at end of file diff --git a/src/token.js b/src/token.js index b857703..b89cc50 100644 --- a/src/token.js +++ b/src/token.js @@ -105,6 +105,18 @@ export class TokenControl{ heart: "#FF0000" }; + } + if (stats == 'CriticalWounds') { /* WFRP4e */ + const criticalWounds = tokenHelper.getCriticalWounds(token); + txt += criticalWounds.value + "/" + criticalWounds.max; + + if (icon == 'stats') + uses = { + available: criticalWounds.value, + maximum: criticalWounds.max, + heart: "#FF0000" + }; + } else if (stats == 'HPbox') { const hp = tokenHelper.getHP(token); @@ -135,7 +147,12 @@ export class TokenControl{ else if (stats == 'Save') txt += tokenHelper.getAbilitySave(token, settings.save); else if (stats == 'Skill') txt += tokenHelper.getSkill(token, settings.skill); else if (stats == 'Prof') txt += tokenHelper.getProficiency(token); - else if (stats == 'Fate') txt += tokenHelper.getFate(token) + else if (stats == 'Fate') txt += tokenHelper.getFate(token) /* WFRP4e */ + else if (stats == 'Fortune') txt += tokenHelper.getFortune(token) /* WFRP4e */ + else if (stats == 'Corruption') txt += tokenHelper.getCorruption(token) /* WFRP4e */ + else if (stats == 'Advantage') txt += tokenHelper.getAdvantage(token) /* WFRP4e */ + else if (stats == 'Resolve') txt += tokenHelper.getResolve(token) /* WFRP4e */ + else if (stats == 'Resilience') txt += tokenHelper.getResilience(token) /* WFRP4e */ if (settings.onClick == 'visibility') { //toggle visibility