From a036315478fd9c52d3f7783d8711d50bf1d20359 Mon Sep 17 00:00:00 2001 From: Nathan Abel Date: Sat, 24 Sep 2022 12:45:12 -0400 Subject: [PATCH 1/3] Fix data accesses, tentative working without turns --- src/module.json | 27 ++++++++++++------- src/scripts/chatter.js | 4 +-- src/scripts/marker.js | 20 +++++++------- src/scripts/markeranimation.js | 10 +++---- src/scripts/settings.js | 48 +++++++++++++++++----------------- src/scripts/settingsForm.js | 3 ++- src/scripts/turnmarker.js | 42 ++++++++++++++--------------- src/scripts/updateWindow.js | 13 ++++----- src/scripts/utils.js | 10 +++---- 9 files changed, 94 insertions(+), 83 deletions(-) diff --git a/src/module.json b/src/module.json index 5910134..6c50932 100644 --- a/src/module.json +++ b/src/module.json @@ -2,16 +2,25 @@ "name": "turnmarker", "title": "Turn Marker", "description": "Displays a (optionally animated) marker on the token who's active turn it is. Originally by Brunhine", - "author": "kckaiwei", - "version": "2.9.0", - "minimumCoreVersion": "9.238", - "compatibleCoreVersion": "9.238", - "manifestPlusVersion": "1.0.0", + "authors": [ + { + "name": "kckaiwei", + "discord": "AdagioT#9507" + }, + { + "name": "nabel", + "discord": "Miles Edgeworth#7948" + } + ], + "version": "2.10.0", + "compatibility": { + "minimum": "10" + }, "esmodules": [ "scripts/turnmarker.js" ], "socket": true, - "styles": ["css/turnmarker.css"], + "styles": ["css/turnmarker.less"], "languages": [ { "lang": "en", @@ -55,7 +64,7 @@ "loop": true } ], - "url": "https://github.com/kckaiwei/TurnMarker-alt", - "manifest": "https://raw.githubusercontent.com/kckaiwei/TurnMarker-alt/v2.9.0/src/module.json", - "download": "https://github.com/kckaiwei/TurnMarker-alt/releases/download/v2.9.0/turnmarker.zip" + "url": "https://github.com/kckaiwei/TurnMarker-alt", + "manifest": "https://raw.githubusercontent.com/kckaiwei/TurnMarker-alt/v2.10.0/src/module.json", + "download": "https://github.com/kckaiwei/TurnMarker-alt/releases/download/v2.10.0/turnmarker.zip" } diff --git a/src/scripts/chatter.js b/src/scripts/chatter.js index 087fedf..5ad9f1e 100644 --- a/src/scripts/chatter.js +++ b/src/scripts/chatter.js @@ -51,8 +51,8 @@ export class Chatter { static placeImage(combatant) { if (Settings.getIncludeAnnounceImage()) { let img = combatant.img; - if (combatant.actor.data.img) { - img = combatant.actor.data.img; + if (combatant.actor.img) { + img = combatant.actor.img; } return `
`; } else return ''; diff --git a/src/scripts/marker.js b/src/scripts/marker.js index 1a3eefc..f90fbf0 100644 --- a/src/scripts/marker.js +++ b/src/scripts/marker.js @@ -42,7 +42,7 @@ export class Marker { if (typeof token !== 'undefined') { let dims = this.getImageDimensions(token, false, "turnmarker"); let center = this.getImageLocation(token, false, "turnmarker"); - const tile = canvas.scene.getEmbeddedCollection('Tile')?.find(t => t.data.flags?.turnMarker === true); + const tile = canvas.scene.getEmbeddedCollection('Tile')?.find(t => t.flags?.turnMarker === true); const updateData = { img: Settings.getImagePath(), width: dims.w, @@ -51,7 +51,7 @@ export class Marker { y: center.y, z: 900, rotation: 0, - hidden: token.data.hidden, + hidden: token.hidden, locked: false }; if (typeof tile === 'undefined') { @@ -77,7 +77,7 @@ export class Marker { if (typeof token !== 'undefined') { let dims = this.getImageDimensions(token, false, "deckmarker"); let center = this.getImageLocation(token, false, "deckmarker"); - let tile = canvas.scene.getEmbeddedCollection('Tile')?.find(t => t.data.flags?.deckMarker === true); + let tile = canvas.scene.getEmbeddedCollection('Tile')?.find(t => t.flags?.deckMarker === true); const updateData = { img: Settings.getOnDeckImagePath(), width: dims.w, @@ -86,7 +86,7 @@ export class Marker { y: center.y, z: 900, rotation: 0, - hidden: token.data.hidden, + hidden: token.hidden, locked: false }; if (typeof tile === 'undefined') { @@ -129,7 +129,7 @@ export class Marker { if (typeof token !== 'undefined') { let dims = this.getImageDimensions(token); let center = this.getImageLocation(token); - let tile = canvas.scene.getEmbeddedCollection('Tile')?.find(t => t.data.flags?.startMarker === true); + let tile = canvas.scene.getEmbeddedCollection('Tile')?.find(t => t.flags?.startMarker === true); const updateData = { img: Settings.getStartMarker(), width: dims.w, @@ -138,7 +138,7 @@ export class Marker { y: center.y, z: 900, rotation: 0, - hidden: token.data.hidden, + hidden: token.hidden, locked: false }; if (typeof tile === 'undefined') { @@ -176,7 +176,7 @@ export class Marker { height: dims.h, x: center.x, y: center.y, - hidden: token.data.hidden + hidden: token.hidden }]); } } @@ -195,7 +195,7 @@ export class Marker { */ static async updateImagePath() { if (game.user.isGM) { - let tile = canvas.scene.tiles.find(t => t.data.flags?.turnMarker == true); + let tile = canvas.scene.tiles.find(t => t.flags?.turnMarker == true); if (tile) { await canvas.scene.updateEmbeddedEntity('Tile', [{ _id: tile.id, @@ -210,7 +210,7 @@ export class Marker { */ static async updateOnDeckImagePath() { if (game.user.isGM) { - let tile = canvas.scene.tiles.find(t => t.data.flags?.deckMarker == true); + let tile = canvas.scene.tiles.find(t => t.flags?.deckMarker == true); if (tile) { await canvas.scene.updateEmbeddedEntity('Tile', [{ _id: tile.id, @@ -286,4 +286,4 @@ export class Marker { return {x: newX, y: newY}; } -} \ No newline at end of file +} diff --git a/src/scripts/markeranimation.js b/src/scripts/markeranimation.js index 9392c78..6dd9b65 100644 --- a/src/scripts/markeranimation.js +++ b/src/scripts/markeranimation.js @@ -66,20 +66,20 @@ export class MarkerAnimation { let tile; switch (marker_type) { case "deckmarker": - tile = canvas.background.tiles.find(t => t.data.flags?.deckMarker == true); + tile = canvas.scene.tiles.find(t => t.flags?.deckMarker == true); break; case "turnmarker": default: - tile = canvas.background.tiles.find(t => t.data.flags?.turnMarker == true); + tile = canvas.scene.tiles.find(t => t.flags?.turnMarker == true); break; } - if (tile?.data.img) { + if (tile?.texture) { let delta = Settings.getInterval() / 10000; try { - tile.tile.rotation += (delta * dt); + tile.rotation += (delta * dt); } catch (err) { // skip lost frames if the tile is being updated by the server } } } -} \ No newline at end of file +} diff --git a/src/scripts/settings.js b/src/scripts/settings.js index 2b00c0f..fffba59 100644 --- a/src/scripts/settings.js +++ b/src/scripts/settings.js @@ -203,7 +203,7 @@ export class Settings { static getStartMarker() { if (game.settings.get(modName, startMarkerImage).trim() == '') { - return 'modules/turnmarker/assets/start.png'; + return `modules/${modName}/assets/start.png`; } else { return game.settings.get(modName, startMarkerImage); } @@ -276,27 +276,27 @@ export class Settings { static getImageByIndex(index) { switch (index) { case 0: - return 'modules/turnmarker/assets/incendium.png'; + return `modules/${modName}/assets/incendium.png`; case 1: - return 'modules/turnmarker/assets/cultist.png'; + return `modules/${modName}/assets/cultist.png`; case 2: - return 'modules/turnmarker/assets/regeneration.png'; + return `modules/${modName}/assets/regeneration.png`; case 3: - return 'modules/turnmarker/assets/cosmos.png'; + return `modules/${modName}/assets/cosmos.png`; case 4: - return 'modules/turnmarker/assets/earthlydust.png'; + return `modules/${modName}/assets/earthlydust.png`; case 5: - return 'modules/turnmarker/assets/reality.png'; + return `modules/${modName}/assets/reality.png`; case 6: - return 'modules/turnmarker/assets/believer.png'; + return `modules/${modName}/assets/believer.png`; case 7: - return 'modules/turnmarker/assets/madmage.png'; + return `modules/${modName}/assets/madmage.png`; case 8: - return 'modules/turnmarker/assets/bluesky.png'; + return `modules/${modName}/assets/bluesky.png`; case 9: - return 'modules/turnmarker/assets/universe.png'; + return `modules/${modName}/assets/universe.png`; case 10: - return 'modules/turnmarker/assets/prosperity.png'; + return `modules/${modName}/assets/prosperity.png`; } } @@ -306,27 +306,27 @@ export class Settings { static getDeckImageByIndex(index) { switch (index) { case 0: - return 'modules/turnmarker/assets/prosperity.png'; + return `modules/${modName}/assets/prosperity.png`; case 1: - return 'modules/turnmarker/assets/incendium.png'; + return `modules/${modName}/assets/incendium.png`; case 2: - return 'modules/turnmarker/assets/cultist.png'; + return `modules/${modName}/assets/cultist.png`; case 3: - return 'modules/turnmarker/assets/regeneration.png'; + return `modules/${modName}/assets/regeneration.png`; case 4: - return 'modules/turnmarker/assets/cosmos.png'; + return `modules/${modName}/assets/cosmos.png`; case 5: - return 'modules/turnmarker/assets/earthlydust.png'; + return `modules/${modName}/assets/earthlydust.png`; case 6: - return 'modules/turnmarker/assets/reality.png'; + return `modules/${modName}/assets/reality.png`; case 7: - return 'modules/turnmarker/assets/believer.png'; + return `modules/${modName}/assets/believer.png`; case 8: - return 'modules/turnmarker/assets/madmage.png'; + return `modules/${modName}/assets/madmage.png`; case 9: - return 'modules/turnmarker/assets/bluesky.png'; + return `modules/${modName}/assets/bluesky.png`; case 10: - return 'modules/turnmarker/assets/universe.png'; + return `modules/${modName}/assets/universe.png`; } } @@ -419,7 +419,7 @@ export class Settings { type: Boolean, default: true, onChange: shouldAnimate => { - if (!game.paused && shouldAnimate && canvas.scene.getEmbeddedCollection('Tile')?.find(t => t.data.flags.turnMarker === true)) { + if (!game.paused && shouldAnimate && canvas.scene.getEmbeddedCollection('Tile')?.find(t => t.flags.turnMarker === true)) { MarkerAnimation.startAnimationGM("turnmarker"); } else { MarkerAnimation.stopAnimationGM("turnmarker"); diff --git a/src/scripts/settingsForm.js b/src/scripts/settingsForm.js index d2c9682..443ba4b 100644 --- a/src/scripts/settingsForm.js +++ b/src/scripts/settingsForm.js @@ -1,4 +1,5 @@ import {imageTitles, deckImageTitles, announcedActorOptions, Settings} from './settings.js'; +import { modName } from './utils.js'; const videos = ['mp4', 'webm', 'ogg']; @@ -15,7 +16,7 @@ export class SettingsForm extends FormApplication { return mergeObject(super.defaultOptions, { id: 'turnmarker-settings-form', title: 'Turn Marker - Global Settings', - template: './modules/turnmarker/templates/settings.html', + template: `./modules/${modName}/templates/settings.html`, classes: ['sheet', 'tm-settings'], width: 500, closeOnSubmit: true diff --git a/src/scripts/turnmarker.js b/src/scripts/turnmarker.js index 325c4a8..8ab3a10 100644 --- a/src/scripts/turnmarker.js +++ b/src/scripts/turnmarker.js @@ -3,7 +3,7 @@ import {Marker} from './marker.js'; import {MarkerAnimation} from './markeranimation.js'; import {Settings} from './settings.js'; import {renderUpdateWindow} from './updateWindow.js'; -import {deleteTile, firstGM, socketName, getNextTurn} from './utils.js'; +import {deleteTile, firstGM, socketName, getNextTurn, modName} from './utils.js'; let lastTurn = ''; @@ -14,7 +14,7 @@ Hooks.once('init', () => { Hooks.once('ready', async () => { if (game.user.isGM) { - if (isNewerVersion(game.modules.get("turnmarker").data.version, Settings.getVersion())) { + if (isNewerVersion(game.modules.get(modName).version, Settings.getVersion())) { renderUpdateWindow(); } } @@ -42,10 +42,10 @@ Hooks.once('ready', async () => { } if (!game.paused) { const tiles = canvas.scene.getEmbeddedCollection('Tile'); - if (Settings.getShouldAnimate('turnmarker') && tiles?.find(t => t.data.flags?.turnMarker === true)) { + if (Settings.getShouldAnimate('turnmarker') && tiles?.find(t => t.flags?.turnMarker === true)) { MarkerAnimation.startAnimation('turnmarker'); } - if (Settings.getShouldAnimate('deckmarker') && tiles?.find(t => t.data.flags?.deckMarker === true)) { + if (Settings.getShouldAnimate('deckmarker') && tiles?.find(t => t.flags?.deckMarker === true)) { MarkerAnimation.startAnimation('deckmarker'); } } @@ -82,7 +82,7 @@ Hooks.on('updateToken', async (tokenDoc, updateData, diff, id) => { // Do onDeck first, so current token will have higher Z-index const tiles = canvas.scene.getEmbeddedCollection('Tile'); - let tile = tiles?.find(t => t.data.flags?.deckMarker == true); + let tile = tiles?.find(t => t.flags?.deckMarker == true); if (tile) { if ((updateData.x || updateData.y || updateData.width || updateData.height || updateData.hidden) && game.combat && game.user.isGM && game.userId === firstGM()) { const nextTurn = getNextTurn(game.combat); @@ -91,7 +91,7 @@ Hooks.on('updateToken', async (tokenDoc, updateData, diff, id) => { } } - tile = tiles?.find(t => t.data.flags?.turnMarker == true); + tile = tiles?.find(t => t.flags?.turnMarker == true); if (tile) { if ((updateData.x || updateData.y || updateData.width || updateData.height || updateData.hidden) && game.combat?.combatant?.token.id === updateData._id && game.user.isGM && game.userId === firstGM()) { await Marker.moveMarkerToToken(updateData._id, tile.id, 'turnmarker'); @@ -100,11 +100,11 @@ Hooks.on('updateToken', async (tokenDoc, updateData, diff, id) => { }); function isVisible(tile) { - if (tile.data.hidden) { + if (tile.hidden) { return game.user.isGM; } - if (!canvas.sight.tokenVision) { + if (!canvas.scene.tokenVision) { return true; } @@ -114,23 +114,23 @@ function isVisible(tile) { const combatant = canvas.scene.tokens.find(t => t.id === game.combat?.combatant.token.id); - if (!combatant || combatant.data.hidden) { + if (!combatant || combatant.hidden) { return game.user.isGM; } let marker_type = "turnmarker"; - if (tile.data.flags.startMarker) { + if (tile.flags.startMarker) { marker_type = "startmarker"; - } else if (tile.data.flags.deckMarker) { + } else if (tile.flags.deckMarker) { marker_type = "deckmarker"; } const ratio = Settings.getRatio(marker_type); - const w = tile.data.width / ratio; - const h = tile.data.height / ratio; + const w = tile.width / ratio; + const h = tile.height / ratio; const tolerance = Math.min(w, h) / 4; - return canvas.sight.testVisibility(tile.center, {tolerance, object: tile}); + return canvas.effects.visibility.testVisibility(tile.center, {tolerance, object: tile}); } async function createCombatDeckMarker(combat) { @@ -191,8 +191,8 @@ async function handleCombatUpdate(combat, update) { } Hooks.on('updateTile', (tileDoc) => { - if (tileDoc.data.flags?.turnMarker || tileDoc.data.flags?.startMarker || tileDoc.data.flags?.deckMarker) { - const tile = canvas.background.tiles.find(t => t.id === tileDoc.data.id); + if (tileDoc.flags?.turnMarker || tileDoc.flags?.startMarker || tileDoc.flags?.deckMarker) { + const tile = canvas.scene.tiles.find(t => t.id === tileDoc.id); if (tile) { tile.renderable = isVisible(tile); } @@ -200,8 +200,8 @@ Hooks.on('updateTile', (tileDoc) => { }); Hooks.on('sightRefresh', () => { - for (const tile of canvas.background.tiles) { - if (tile.data.flags?.turnMarker || tile.data.flags?.startMarker || tile.data.flags?.deckMarker) { + for (const tile of canvas.scene.tiles) { + if (tile.flags?.turnMarker || tile.flags?.startMarker || tile.flags?.deckMarker) { tile.renderable = isVisible(tile); } } @@ -209,13 +209,13 @@ Hooks.on('sightRefresh', () => { Hooks.on('pauseGame', (isPaused) => { if (!isPaused) { - if (Settings.getShouldAnimate("turnmarker") && canvas.scene.getEmbeddedCollection('Tile')?.find(t => t.data.flags?.turnMarker === true)) { + if (Settings.getShouldAnimate("turnmarker") && canvas.scene.getEmbeddedCollection('Tile')?.find(t => t.flags?.turnMarker === true)) { MarkerAnimation.startAnimation("turnmarker"); } - if (Settings.getShouldAnimate("deckmarker") && canvas.scene.getEmbeddedCollection('Tile')?.find(t => t.data.flags?.deckMarker === true)) { + if (Settings.getShouldAnimate("deckmarker") && canvas.scene.getEmbeddedCollection('Tile')?.find(t => t.flags?.deckMarker === true)) { MarkerAnimation.startAnimation("deckmarker"); } } else { MarkerAnimation.stopAllAnimation(); } -}); \ No newline at end of file +}); diff --git a/src/scripts/updateWindow.js b/src/scripts/updateWindow.js index 8029c92..5ae722b 100644 --- a/src/scripts/updateWindow.js +++ b/src/scripts/updateWindow.js @@ -1,9 +1,10 @@ import { Settings } from './settings.js'; +import { modName } from './utils.js'; export function renderUpdateWindow() { - const module = game.modules.get("turnmarker"); + const module = game.modules.get(modName); - if (!isNewerVersion(module.data.version, Settings.getVersion())) + if (!isNewerVersion(module.version, Settings.getVersion())) return; class UpdateWindow extends Application { @@ -14,13 +15,13 @@ export function renderUpdateWindow() { width: 500, height: 600, classes: ["updateWindow"], - title: `${module.data.title} - Updated` + title: `${module.title} - Updated` }); } getData() { return { - version: module.data.version + version: module.version }; } @@ -28,10 +29,10 @@ export function renderUpdateWindow() { super.activateListeners(html); html.find('.show-again').on('change', ev => { - Settings.setVersion(ev.currentTarget.checked ? module.data.version : null); + Settings.setVersion(ev.currentTarget.checked ? module.version : null); }); } } new UpdateWindow().render(true); -} \ No newline at end of file +} diff --git a/src/scripts/utils.js b/src/scripts/utils.js index 1dcf297..6c1e0b5 100644 --- a/src/scripts/utils.js +++ b/src/scripts/utils.js @@ -5,7 +5,7 @@ export const modName = 'turnmarker'; /** Socket Info */ -export const socketName = 'module.turnmarker'; +export const socketName = `module.${modName}`; export const socketAction = { deleteStartMarker: 1, deleteTurnMarker: 2, @@ -34,7 +34,7 @@ export function findTileById(tileId) { */ export function firstGM() { for (let user of game.users.contents) { - if (user.data.role === CONST.USER_ROLES.GAMEMASTER && user.active) { + if (user.role === CONST.USER_ROLES.GAMEMASTER && user.active) { return user.id; } } @@ -57,19 +57,19 @@ export async function deleteTile({ mode } = {}) { let tiles = null switch (mode) { case socketAction.deleteStartMarker: - tiles = canvas.scene.getEmbeddedCollection('Tile')?.filter(t => t.data.flags?.startMarker === true)?.map(t => t.id) + tiles = canvas.scene.getEmbeddedCollection('Tile')?.filter(t => t.flags?.startMarker === true)?.map(t => t.id) if (tiles?.length > 0) { await canvas.scene.deleteEmbeddedDocuments('Tile', tiles) } break case socketAction.deleteTurnMarker: - tiles = canvas.scene.getEmbeddedCollection('Tile')?.filter(t => t.data.flags?.turnMarker === true)?.map(t => t.id) + tiles = canvas.scene.getEmbeddedCollection('Tile')?.filter(t => t.flags?.turnMarker === true)?.map(t => t.id) if (tiles?.length > 0) { await canvas.scene.deleteEmbeddedDocuments('Tile', tiles) } break case socketAction.deleteOnDeckMarker: - tiles = canvas.scene.getEmbeddedCollection('Tile')?.filter(t => t.data.flags?.deckMarker === true)?.map(t => t.id) + tiles = canvas.scene.getEmbeddedCollection('Tile')?.filter(t => t.flags?.deckMarker === true)?.map(t => t.id) if (tiles?.length > 0) { await canvas.scene.deleteEmbeddedDocuments('Tile', tiles) } From 136fd700a28a5a20f7b9105439ca7997ef06554b Mon Sep 17 00:00:00 2001 From: Nathan Abel Date: Sat, 24 Sep 2022 16:43:36 -0400 Subject: [PATCH 2/3] Rotation working --- src/lang/de.json | 4 +- src/lang/en.json | 4 +- src/lang/es.json | 4 +- src/lang/ja.json | 4 +- src/lang/ko.json | 4 +- src/lang/zh-tw.json | 4 +- src/scripts/marker.js | 4 +- src/scripts/markeranimation.js | 122 +++++++++++++++++++-------------- src/scripts/settings.js | 25 +++---- src/scripts/turnmarker.js | 18 ++--- 10 files changed, 103 insertions(+), 90 deletions(-) diff --git a/src/lang/de.json b/src/lang/de.json index 3fff3ec..c2303b6 100644 --- a/src/lang/de.json +++ b/src/lang/de.json @@ -22,9 +22,9 @@ "name": "Animierte Markierung?", "hint": "Verwende eine rotierende Animation für die Markierung. (Veränderungen sind eventuell erst beim Start eines neuen Kampfes sichtbar)" }, - "interval": { + "speed": { "name": "Animationsgeschwindigkeit", - "hint": "Wie schnell soll die Animation rotieren, falls die Animation eingeschaltet ist (Empfohlen wird zwischen 10 und 200)" + "hint": "Wie schnell soll die Animation rotieren, falls die Animation eingeschaltet ist" }, "image": { "name": "Bild für die Markierung" diff --git a/src/lang/en.json b/src/lang/en.json index c1021b4..fb9da90 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -27,9 +27,9 @@ "name": "Animate Turn Marker?", "hint": "Use rotation animation on turn marker. (changes may not be visible until a new combat is started)" }, - "interval": { + "speed": { "name": "Animation Speed", - "hint": "How fast to animate the rotation if enabled (recommended between 10 and 200)" + "hint": "How fast to animate the rotation if enabled" }, "image": { "name": "Marker Image" diff --git a/src/lang/es.json b/src/lang/es.json index 78198dc..2c368dc 100644 --- a/src/lang/es.json +++ b/src/lang/es.json @@ -31,9 +31,9 @@ "name": "¿Marcador animado?", "hint": "Aplicar animación de rotación al marcador. Los cambios no serán visibles hasta que se inicie un nuevo combate" }, - "interval": { + "speed": { "name": "Velocidad de la animación", - "hint": "Velocidad a la que se moverá la animación en caso de activarla (se recomienda entre 10 y 200)" + "hint": "Velocidad a la que se moverá la animación en caso de activarla" }, "image": { "name": "Imagen del marcador" diff --git a/src/lang/ja.json b/src/lang/ja.json index 4809c7a..64cb98c 100644 --- a/src/lang/ja.json +++ b/src/lang/ja.json @@ -22,9 +22,9 @@ "name": "回転アニメーション", "hint": "マーカに回転アニメーションを適用します。(新しい戦闘を開始するまで設定は適用されません)" }, - "interval": { + "speed": { "name": "アニメーション速度", - "hint": "回転アニメーションの速度を設定します。(10~200の間が推薦されています)" + "hint": "回転アニメーションの速度を設定します。" }, "image": { "name": "マーカ画像" diff --git a/src/lang/ko.json b/src/lang/ko.json index 86b1a12..335be54 100644 --- a/src/lang/ko.json +++ b/src/lang/ko.json @@ -27,9 +27,9 @@ "name": "마커를 움직입니까?", "hint": "마커에 회전 애니메이션을 적용한다. (새 전투가 시작되기 전까지는 변경점이 보이지 않을 수 있음)" }, - "interval": { + "speed": { "name": "애니메이션 속도", - "hint": "활성화 되었을 때 애니메이션이 회전하는 속도. (10 ~ 200 사이를 권장)" + "hint": "활성화 되었을 때 애니메이션이 회전하는 속도." }, "image": { "name": "표식 이미지" diff --git a/src/lang/zh-tw.json b/src/lang/zh-tw.json index b177175..f987053 100644 --- a/src/lang/zh-tw.json +++ b/src/lang/zh-tw.json @@ -27,9 +27,9 @@ "name": "動畫化 回合標記?", "hint": "在回合標記上使用使用旋轉動畫. (變更可能要等到新的戰鬥開始後才能看到)" }, - "interval": { + "speed": { "name": "動畫速度", - "hint": "啟用時旋轉動畫的速度(建議在10到200之間)" + "hint": "啟用時旋轉動畫的速度" }, "image": { "name": "標記 圖片" diff --git a/src/scripts/marker.js b/src/scripts/marker.js index f90fbf0..1d61b80 100644 --- a/src/scripts/marker.js +++ b/src/scripts/marker.js @@ -50,7 +50,7 @@ export class Marker { x: center.x, y: center.y, z: 900, - rotation: 0, + rotation: tile ? tile.rotation : 0, hidden: token.hidden, locked: false }; @@ -85,7 +85,7 @@ export class Marker { x: center.x, y: center.y, z: 900, - rotation: 0, + rotation: tile ? tile.rotation : 0, hidden: token.hidden, locked: false }; diff --git a/src/scripts/markeranimation.js b/src/scripts/markeranimation.js index 6dd9b65..1636a0c 100644 --- a/src/scripts/markeranimation.js +++ b/src/scripts/markeranimation.js @@ -1,70 +1,90 @@ -import {Settings} from './settings.js'; -import {socketName} from './utils.js'; +import { firstGM } from './utils.js'; +import { Settings } from './settings.js'; +const rotationDelta = 0.50; // How much to rotate by when the timer fires +const totalRotationTime = 60; // How long it should take for a full rotation by default. + +/** + * Methods here can be called from all users, they will only be run once. This is ensured through checks against firstGM. + */ export class MarkerAnimation { /** - * Starts the animation loop + * Starts the animation loop for a certain type of marker + * @param {string} marker_type - type of marker to start animating */ - static startAnimationGM(marker_type = "turnmarker") { - MarkerAnimation.startAnimation(marker_type) - game.socket.emit(socketName, { - startAnimation: marker_type - }); - } + static startAnimation(marker_type) { + if (firstGM() === game.userId) { - static startAnimation(marker_type = "turnmarker") { - if (!this.animators) { - this.animators = {}; - } - if (marker_type in this.animators) { - return this.animators[marker_type]; + if (!this.animators) { + this.animators = {}; + } + if (marker_type in this.animators) { + return this.animators[marker_type]; + } + this.animators[marker_type] = new Animator(marker_type); + return this.animators; } - this.animators[marker_type] = this.animateRotation.bind(this, marker_type); - canvas.app.ticker.add(this.animators[marker_type]); - return this.animators; } /** - * Stops the animation loop + * Stops the animation loop for a certain type of marker + * @param {string} marker_type - type of marker to stop animating */ - static stopAnimationGM(marker_type = "turnmarker") { - MarkerAnimation.startAnimation(marker_type) - game.socket.emit(socketName, { - stopAnimation: marker_type - }); + static stopAnimation(marker_type) { + if (firstGM() === game.userId) { + MarkerAnimation.startAnimation(marker_type); // Make sure something's there before we delete it. + if (this.animators) { + this.animators[marker_type].stopAnimation(); + delete this.animators[marker_type]; + } + } } - static stopAnimation(marker_type = "turnmarker") { - if (this.animators) { - canvas.app.ticker.remove(this.animators[marker_type]); - delete this.animators[marker_type]; + /** + * Tells all currently running animators to stop their rotations. Then drops the table of animators. + */ + static stopAllAnimation() { + if (firstGM() === game.userId) { + if (this.animators) { + for (const [, value] of Object.entries(this.animators)) { + value.stopAnimation(); + } + this.animators = {}; + } } } +} - static stopAllAnimationGM() { - MarkerAnimation.stopAllAnimation() - game.socket.emit(socketName, { - stopAllAnimation: 'all' - }); +class Animator { + /** + * Manages animating a specific set of markers. Construction begins animation. + * @param {string} marker_type - type of markers managed + */ + constructor(marker_type) { + /** + * Speed forumla is such that a speed of 1 will rotate in the total rotation time. + * Lower speed values should slow the animation, and higher values should speed it up. + */ + const base_update_freq = (360 / rotationDelta) / totalRotationTime; // In Hertz + const interval = (1 / (base_update_freq * Settings.getSpeed())) * 1000; // Hertz to seconds, account for speedup, and convert to milliseconds + + this.marker_type = marker_type; + this.timeout = setInterval(this.rotateMarker.bind(this), interval); } - static stopAllAnimation() { - if (this.animators) { - for (const [, value] of Object.entries(this.animators)) { - canvas.app.ticker.remove(value); - } - this.animators = {}; - } + /** + * Tell the interval timer to stop calling rotateMarker. + */ + stopAnimation() { + clearInterval(this.timeout); } /** - * Called on every tick of the animation loop to rotate the image based on the current frame - * @param {string} marker_type - type of marker to animate - * @param {number} dt - The delta time + * Rotate the marker. Called periodically by setInterval when the class is constructed. */ - static animateRotation(marker_type, dt) { + async rotateMarker() { let tile; - switch (marker_type) { + switch (this.marker_type) { case "deckmarker": tile = canvas.scene.tiles.find(t => t.flags?.deckMarker == true); break; @@ -73,13 +93,11 @@ export class MarkerAnimation { tile = canvas.scene.tiles.find(t => t.flags?.turnMarker == true); break; } - if (tile?.texture) { - let delta = Settings.getInterval() / 10000; - try { - tile.rotation += (delta * dt); - } catch (err) { - // skip lost frames if the tile is being updated by the server - } + try { + await tile.object.rotate(tile.rotation + rotationDelta, 0.001); + } catch (err) { + // If the tile has disappeared between finding it and trying to rotate it, it's probably been deleted. + // That's not a problem, so just fail silently. } } } diff --git a/src/scripts/settings.js b/src/scripts/settings.js index fffba59..e9aad20 100644 --- a/src/scripts/settings.js +++ b/src/scripts/settings.js @@ -4,7 +4,7 @@ import {SettingsForm} from './settingsForm.js'; import {modName, getNextTurn} from './utils.js'; const version = 'tm-version'; -const interval = 'interval'; +const speed = 'speed'; const announce = 'announce-turn'; const announceActors = 'announce-Actors'; const announceImage = 'announce-image'; @@ -119,10 +119,11 @@ export class Settings { } /** - * Gets the animation interval in ms. + * Gets the animation speed. + * @returns A speed multiplier, with 1 being the default. */ - static getInterval() { - return game.settings.get(modName, interval); + static getSpeed() { + return game.settings.get(modName, speed); } /** @@ -420,9 +421,9 @@ export class Settings { default: true, onChange: shouldAnimate => { if (!game.paused && shouldAnimate && canvas.scene.getEmbeddedCollection('Tile')?.find(t => t.flags.turnMarker === true)) { - MarkerAnimation.startAnimationGM("turnmarker"); + MarkerAnimation.startAnimation("turnmarker"); } else { - MarkerAnimation.stopAnimationGM("turnmarker"); + MarkerAnimation.stopAnimation("turnmarker"); } } }); @@ -436,20 +437,20 @@ export class Settings { default: true, onChange: shouldAnimate => { if (!game.paused && shouldAnimate && canvas.scene.getEmbeddedCollection('Tile')?.find(t => t.data.flags.deckMarker === true)) { - MarkerAnimation.startAnimationGM("deckmarker"); + MarkerAnimation.startAnimation("deckmarker"); } else { - MarkerAnimation.stopAnimationGM("deckmarker"); + MarkerAnimation.stopAnimation("deckmarker"); } } }); - game.settings.register(modName, interval, { - name: 'tm.settings.interval.name', - hint: 'tm.settings.interval.hint', + game.settings.register(modName, speed, { + name: 'tm.settings.speed.name', + hint: 'tm.settings.speed.hint', scope: 'user', config: true, type: Number, - default: 100 + default: 1 }); game.settings.register(modName, image, { diff --git a/src/scripts/turnmarker.js b/src/scripts/turnmarker.js index 8ab3a10..72d7509 100644 --- a/src/scripts/turnmarker.js +++ b/src/scripts/turnmarker.js @@ -24,12 +24,6 @@ Hooks.once('ready', async () => { if (data.mode) { deleteTile({ mode: data.mode }); } - } else if (data.startAnimation) { - MarkerAnimation.startAnimation(data.startAnimation) - } else if (data.stopAnimation) { - MarkerAnimation.stopAnimation(data.stopAnimation) - } else if (data.stopAllAnimation) { - MarkerAnimation.stopAllAnimation() } }); @@ -72,7 +66,7 @@ Hooks.on("renderCombatTracker", async (combatTracker, update) => { Hooks.on('deleteCombat', async () => { await Marker.clearAllMarkers(); - MarkerAnimation.stopAllAnimationGM(); + MarkerAnimation.stopAllAnimation(); }); Hooks.on('updateToken', async (tokenDoc, updateData, diff, id) => { @@ -139,7 +133,7 @@ async function createCombatDeckMarker(combat) { if (combat.turns[nextTurn].actor.hasPlayerOwner) { await Marker.placeOnDeckMarker(combat.turns[nextTurn].token.id).then(function () { if (!game.paused && Settings.getShouldAnimate("deckmarker")) { - MarkerAnimation.startAnimationGM("deckmarker"); + MarkerAnimation.startAnimation("deckmarker"); } }); } else { @@ -147,9 +141,9 @@ async function createCombatDeckMarker(combat) { } } else { await Marker.placeOnDeckMarker(combat.turns[nextTurn].token.id).then(function () { - if (!game.paused && Settings.getShouldAnimate("deckmarker")) { - MarkerAnimation.startAnimationGM("deckmarker"); - } + if (!game.paused && Settings.getShouldAnimate("deckmarker")) { + MarkerAnimation.startAnimation("deckmarker"); + } }); } } @@ -163,7 +157,7 @@ async function handleCombatUpdate(combat, update) { await createCombatDeckMarker(combat); await Marker.placeTurnMarker(combat.combatant.token.id).then(function () { if (!game.paused && Settings.getShouldAnimate("turnmarker")) { - MarkerAnimation.startAnimationGM("turnmarker"); + MarkerAnimation.startAnimation("turnmarker"); } }); if (Settings.shouldAnnounceTurns() && !combat.combatant.hidden) { From 9ef35ebb590166bf79ee14b7763d1f30955a4ed6 Mon Sep 17 00:00:00 2001 From: Nathan Abel Date: Sat, 24 Sep 2022 16:51:06 -0400 Subject: [PATCH 3/3] Fix setting new image --- src/scripts/marker.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/scripts/marker.js b/src/scripts/marker.js index 1d61b80..4b02a0d 100644 --- a/src/scripts/marker.js +++ b/src/scripts/marker.js @@ -197,10 +197,9 @@ export class Marker { if (game.user.isGM) { let tile = canvas.scene.tiles.find(t => t.flags?.turnMarker == true); if (tile) { - await canvas.scene.updateEmbeddedEntity('Tile', [{ - _id: tile.id, + await tile.update({ img: Settings.getImagePath() - }]); + }); } } } @@ -212,10 +211,10 @@ export class Marker { if (game.user.isGM) { let tile = canvas.scene.tiles.find(t => t.flags?.deckMarker == true); if (tile) { - await canvas.scene.updateEmbeddedEntity('Tile', [{ + await tile.update({ _id: tile.id, img: Settings.getOnDeckImagePath() - }]); + }); } } }