Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to V10 #107

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/lang/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
4 changes: 2 additions & 2 deletions src/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
4 changes: 2 additions & 2 deletions src/lang/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
4 changes: 2 additions & 2 deletions src/lang/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
"name": "回転アニメーション",
"hint": "マーカに回転アニメーションを適用します。(新しい戦闘を開始するまで設定は適用されません)"
},
"interval": {
"speed": {
"name": "アニメーション速度",
"hint": "回転アニメーションの速度を設定します。(10~200の間が推薦されています)"
"hint": "回転アニメーションの速度を設定します。"
},
"image": {
"name": "マーカ画像"
Expand Down
4 changes: 2 additions & 2 deletions src/lang/ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@
"name": "마커를 움직입니까?",
"hint": "마커에 회전 애니메이션을 적용한다. (새 전투가 시작되기 전까지는 변경점이 보이지 않을 수 있음)"
},
"interval": {
"speed": {
"name": "애니메이션 속도",
"hint": "활성화 되었을 때 애니메이션이 회전하는 속도. (10 ~ 200 사이를 권장)"
"hint": "활성화 되었을 때 애니메이션이 회전하는 속도."
},
"image": {
"name": "표식 이미지"
Expand Down
4 changes: 2 additions & 2 deletions src/lang/zh-tw.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@
"name": "動畫化 回合標記?",
"hint": "在回合標記上使用使用旋轉動畫. (變更可能要等到新的戰鬥開始後才能看到)"
},
"interval": {
"speed": {
"name": "動畫速度",
"hint": "啟用時旋轉動畫的速度(建議在10到200之間)"
"hint": "啟用時旋轉動畫的速度"
},
"image": {
"name": "標記 圖片"
Expand Down
27 changes: 18 additions & 9 deletions src/module.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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"
}
4 changes: 2 additions & 2 deletions src/scripts/chatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<div style="flex:3;padding-right:4px"><img src="${img}" style="border: none;" /></div>`;
} else return '';
Expand Down
33 changes: 16 additions & 17 deletions src/scripts/marker.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,16 @@ 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,
height: dims.h,
x: center.x,
y: center.y,
z: 900,
rotation: 0,
hidden: token.data.hidden,
rotation: tile ? tile.rotation : 0,
hidden: token.hidden,
locked: false
};
if (typeof tile === 'undefined') {
Expand All @@ -77,16 +77,16 @@ 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,
height: dims.h,
x: center.x,
y: center.y,
z: 900,
rotation: 0,
hidden: token.data.hidden,
rotation: tile ? tile.rotation : 0,
hidden: token.hidden,
locked: false
};
if (typeof tile === 'undefined') {
Expand Down Expand Up @@ -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,
Expand All @@ -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') {
Expand Down Expand Up @@ -176,7 +176,7 @@ export class Marker {
height: dims.h,
x: center.x,
y: center.y,
hidden: token.data.hidden
hidden: token.hidden
}]);
}
}
Expand All @@ -195,12 +195,11 @@ 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,
await tile.update({
img: Settings.getImagePath()
}]);
});
}
}
}
Expand All @@ -210,12 +209,12 @@ 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', [{
await tile.update({
_id: tile.id,
img: Settings.getOnDeckImagePath()
}]);
});
}
}
}
Expand Down Expand Up @@ -286,4 +285,4 @@ export class Marker {

return {x: newX, y: newY};
}
}
}
128 changes: 73 additions & 55 deletions src/scripts/markeranimation.js
Original file line number Diff line number Diff line change
@@ -1,85 +1,103 @@
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.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) {
let delta = Settings.getInterval() / 10000;
try {
tile.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.
}
}
}
}
Loading