Skip to content
This repository was archived by the owner on Sep 18, 2024. It is now read-only.

Commit 6e28d56

Browse files
authored
Merge pull request #118 from death-save:v0.2.5
V0.2.5
2 parents fe15f02 + e7072d7 commit 6e28d56

File tree

11 files changed

+153
-92
lines changed

11 files changed

+153
-92
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,18 @@
66
- Some strings are still not setup for translation
77
- When multiple combatants are added to combat at the same time, and the `Control Active Combatant` setting is enabled, there will be an error in console. It doesn't appear to prevent any Carousel behaviour.
88

9+
## [0.2.5] - 2021-12-27
10+
> This update adds compatibility for Foundry VTT V9
11+
12+
- Combat Carousel no longer throws an error if you have a world with no active combat
13+
- Spanish translation update (again, thanks @lozalojo 🎉)
14+
- Nav bar automagically re-expands after combat if the collapse setting is enabled (thanks @sirrus233 🎉)
15+
- Added a setting to open the Carousel on combat creation
16+
- Lengthened the delay for the fly-in effect on cards when the Carousel is opened
17+
- Occasionally the Carousel got confused about its collapsed/expanded state. Should happen less now
18+
- Added additional update properties for actors and tokens that cause the Carousel UI to update
19+
- Carousel now collapses when combat is deleted
20+
921
## [0.2.3] - 2021-10-11
1022
- Spanish translation updated (thanks @lozalojo ! 🎉)
1123
- Added options for `Limited` Actor permission to settings that support permissions (thanks @SovietVVinter ! 🎉)

lang/en.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@
3535
"ControlActiveCombatantTokenN": "Control Active Combatant's Token",
3636
"ControlActiveCombatantTokenH": "Enable to automatically control (select) the token associated to the currently Active Combatant.",
3737
"PanOnClickN": "Pan on Card Click",
38-
"PanOnClickH": "Pans to the matching token when a card is clicked (note: the token must be 'visible' to the current user)"
38+
"PanOnClickH": "Pans to the matching token when a card is clicked (note: the token must be 'visible' to the current user)",
39+
"AlwaysOnTopN": "Always On Top",
40+
"AlwaysOnTopH": "Always render the Carousel above other UI elements.",
41+
"OpenOnCombatCreateN": "Open Combat Carousel on Combat Creation",
42+
"OpenOnCombatCreateH": "Opens the Carousel when a Combat is created"
3943
},
4044

4145
"CAROUSEL": {

lang/es.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@
3838
"CarouselSizeN": "Tamaño del carrusel",
3939
"CarouselSizeH": "El tamaño del carrusel en la pantalla. No se rescalarán los elementos de control ni el HUD",
4040
"ControlActiveCombatantTokenN": "Controlar icono del contendiente activo",
41-
"ControlActiveCombatantTokenH": "Habilita el control automático (seleccionar) del icono asociado al contendiente activo actualmente"
41+
"ControlActiveCombatantTokenH": "Habilita el control automático (seleccionar) del icono asociado al contendiente activo actualmente",
42+
"PanOnClickN": "Centrar al hacer clic en una tarjeta",
43+
"PanOnClickH": "Se centra en el icono correspondiente cuando se hace clic en una tarjeta (nota: el icono debe ser 'visible' para el usuario actual)"
4244
},
4345

4446
"CAROUSEL": {

module.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "combat-carousel",
33
"title": "Combat Carousel",
44
"description": "Adds a CRPG-style combat tracker to the top of the screen",
5-
"version": "0.2.3",
5+
"version": "0.2.5",
66
"author": "Evan Clarke [errational#2007]",
77
"authors": [
88
{
@@ -14,8 +14,8 @@
1414
"patreon": "deathsave"
1515
}
1616
],
17-
"minimumCoreVersion": "0.8.5",
18-
"compatibleCoreVersion": "0.8.9",
17+
"minimumCoreVersion": "9.235",
18+
"compatibleCoreVersion": "9.238",
1919
"url": "https://github.com/death-save/combat-carousel",
2020
"manifest": "https://github.com/death-save/combat-carousel/releases/latest/download/module.json",
2121
"download": "https://github.com/death-save/combat-carousel/releases/latest/download/module.zip",
@@ -76,8 +76,8 @@
7676
"caption":"Combat Carousel launch video"
7777
}
7878
],
79-
"manifestPlusVersion": "1.2.0",
8079
"flags": {
80+
"manifestPlusVersion": "1.2.0",
8181
"allowBugReporter": true
8282
}
8383
}

modules/combat-carousel.mjs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,15 @@ export default class CombatCarousel extends Application {
5050
// Instantiate the Fixed Draggable to make this app draggable
5151
new FixedDraggable(this, this.element, this.element.find(".drag-handle")[0], this.options.resizeable, {onDragMouseUp: this._onDragEnd});
5252

53-
// If set, collapse the Nav bar
54-
const collapseNavSetting = game.settings.get(NAME, SETTING_KEYS.collapseNav);
55-
56-
if (collapseNavSetting && game.combat) ui.nav.collapse();
57-
5853
const sizeSetting = game.settings.get(NAME, SETTING_KEYS.carouselSize);
5954
const scale = this.sizeFactor = sizeSetting ? DEFAULT_CONFIG.carouselSize.sizeScaleMap[sizeSetting] : 1;
6055

56+
const alwaysOnTopSetting = game.settings.get(NAME, SETTING_KEYS.alwaysOnTop);
57+
58+
if (alwaysOnTopSetting) {
59+
this.element[0].style.zIndex = 100;
60+
}
61+
6162
/**
6263
* Create a Splide instance and store it for later use
6364
*/
@@ -90,7 +91,7 @@ export default class CombatCarousel extends Application {
9091
if (force) {
9192
for (let i = 0; i < slides.length; i++) {
9293
slides[i].classList.add("fly");
93-
slides[i].style.animationDelay = `${0.1 * (i ? i : 1)}s`;
94+
slides[i].style.animationDelay = `${0.2 * (i ? i + 1 : 1)}s`;
9495

9596
slides[i].addEventListener("animationend", event => {
9697
event.target.classList.remove("fly");
@@ -172,6 +173,7 @@ export default class CombatCarousel extends Application {
172173
await this.splide.mount();
173174

174175
this.setPosition({width: this._getMinimumWidth(), height: 205 * scale});
176+
this._collapsed = false;
175177
}
176178

177179
/**
@@ -246,7 +248,7 @@ export default class CombatCarousel extends Application {
246248
img,
247249
initiative: turn.initiative,
248250
hidden: turn.hidden,
249-
visible: turn.isVisible,
251+
visible: turn.visible,
250252
defeated: turn.data.defeated,
251253
carousel: {
252254
isGM: game.user.isGM,
@@ -424,8 +426,11 @@ export default class CombatCarousel extends Application {
424426

425427
const ccButtonHtml = await renderTemplate(`${TEMPLATE_PATH}/combat-carousel-button.hbs`,{carouselIcon});
426428

427-
html.append(ccButtonHtml);
429+
const mainControls = html.find(".control-tools.main-controls");
430+
431+
if (!mainControls?.length) return;
428432

433+
mainControls.append(ccButtonHtml);
429434
const ccButton = html.find("li[data-control='combat-carousel']");
430435

431436
ccButton
@@ -536,7 +541,7 @@ export default class CombatCarousel extends Application {
536541

537542
const token = canvas.tokens.get(combatant.token.id);
538543

539-
if (!token.owner) return;
544+
if (!token.isOwner) return;
540545

541546
if (!combatant.initiative) game.combat.rollInitiative(combatantId);
542547
}
@@ -703,7 +708,7 @@ export default class CombatCarousel extends Application {
703708

704709
if (!combatant) return;
705710

706-
const isCtrl = game.keyboard.isCtrl(event);
711+
const isCtrl = game.keyboard.isModifierActive(KeyboardManager.MODIFIER_KEYS.CONTROL);
707712

708713
if (isCtrl && game.user.isGM) {
709714

@@ -741,7 +746,7 @@ export default class CombatCarousel extends Application {
741746
const combatantId = card.dataset.combatantId;
742747
const token = getTokenFromCombatantId(combatantId);
743748

744-
if (!game.user.isGM || !token.owner) return;
749+
if (!game.user.isGM || !token.isOwner) return;
745750

746751
token.actor.sheet.render(true);
747752
}

modules/config.mjs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ export const SETTING_KEYS = {
5656
initiativePermission: "initiativePermission",
5757
imageType: "imageType",
5858
controlActiveCombatantToken: "controlActiveCombatantToken",
59-
panOnClick: "panOnClick"
59+
panOnClick: "panOnClick",
60+
alwaysOnTop: "alwaysOnTop",
61+
openOnCombatCreate: "openOnCombatCreate"
6062
}
6163

6264
/**

modules/hooks.mjs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,16 @@ export default function registerHooks() {
4747
*/
4848
Hooks.on("createCombat", async (combat, createData, options, userId) => {
4949
const enabled = game.settings.get(NAME, SETTING_KEYS.enabled);
50+
const openOnCreate = game.settings.get(NAME, SETTING_KEYS.openOnCombatCreate);
5051

51-
if (!enabled || !ui.combatCarousel || ui.combatCarousel?._collapsed) return;
52+
if (!enabled || !ui.combatCarousel || (ui.combatCarousel?._collapsed && !openOnCreate)) return;
5253

5354
ui.combatCarousel.render(true);
54-
55+
56+
// If set, collapse the Nav bar
57+
const collapseNavSetting = game.settings.get(NAME, SETTING_KEYS.collapseNav);
58+
if (collapseNavSetting) ui.nav.collapse();
59+
5560
const hasTurns = combat?.turns?.length;
5661
const carouselImg = ui?.controls?.element.find("img.carousel-icon");
5762
const newImgSrc = hasTurns ? CAROUSEL_ICONS.hasTurns : CAROUSEL_ICONS.noTurns;
@@ -107,9 +112,8 @@ export default function registerHooks() {
107112

108113
if (!enabled || ui.combatCarousel?._collapsed) return;
109114

110-
const hasCombat = game.combats.entities?.length;
111-
112-
if (!hasCombat) {
115+
if (!game.combat) {
116+
await ui.combatCarousel.collapse();
113117
ui.combatCarousel.close();
114118
//await ui.combatCarousel.render(true);
115119
//ui.combatCarousel.collapse();
@@ -223,9 +227,9 @@ export default function registerHooks() {
223227
Hooks.on("updateActor", (actor, updateData, options, userId) => {
224228
const enabled = game.settings.get(NAME, SETTING_KEYS.enabled);
225229

226-
if (!enabled || ui.combatCarousel?._collapsed) return;
230+
if (!enabled || !game.combat || ui.combatCarousel?._collapsed) return;
227231

228-
if (!hasProperty(updateData, "data.attributes.hp.value") && !hasProperty(updateData, "img")) return;
232+
if (!hasProperty(updateData, "data.attributes.hp") && !hasProperty(updateData, "img") && !hasProperty(updateData, "name")) return;
229233
// find any matching combat carousel combatants
230234

231235
if (!game.combat?.combatants.some(c => c.actor.id === actor.id)) return;
@@ -239,16 +243,15 @@ export default function registerHooks() {
239243
Hooks.on("updateToken", (token, updateData, options, userId) => {
240244
const enabled = game.settings.get(NAME, SETTING_KEYS.enabled);
241245

242-
if (!enabled || ui.combatCarousel?._collapsed) return;
246+
if (!enabled || !game.combat || ui.combatCarousel?._collapsed) return;
243247

244248
//console.log("token update:", scene,token,update,options,userId);
245249
if (
246250
!hasProperty(updateData, "effects")
247251
&& !hasProperty(updateData, "overlayEffect")
248-
&& !hasProperty(updateData, "actorData.effects")
249-
&& !hasProperty(updateData, "actorData.data.attributes.hp.value")
252+
&& !hasProperty(updateData, "actorData")
250253
&& !hasProperty(updateData, "img")
251-
&& !hasProperty(updateData, "actorData.img")
254+
&& !hasProperty(updateData, "name")
252255
) return;
253256
// find any matching combat carousel combatants
254257

@@ -297,6 +300,9 @@ export default function registerHooks() {
297300

298301
if (!data?.hasCombat && rendered) {
299302
ui.combatCarousel.close();
303+
// If set, re-expand the nav bar after combat closes
304+
const collapseNavSetting = game.settings.get(NAME, SETTING_KEYS.collapseNav);
305+
if (collapseNavSetting) ui.nav.expand();
300306
}
301307

302308
if (data?.hasCombat && isViewedCombat && !combatMatch && collapsed === false) {

modules/settings.mjs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,18 @@ export default function registerSettings() {
7777
}
7878
});
7979

80+
game.settings.register(NAME, SETTING_KEYS.openOnCombatCreate, {
81+
name: "COMBAT_CAROUSEL.SETTINGS.OpenOnCombatCreateN",
82+
hint: "COMBAT_CAROUSEL.SETTINGS.OpenOnCombatCreateH",
83+
scope: "client",
84+
type: Boolean,
85+
default: false,
86+
config: true,
87+
onChange: s => {
88+
89+
}
90+
});
91+
8092
game.settings.register(NAME, SETTING_KEYS.carouselSize, {
8193
name: "COMBAT_CAROUSEL.SETTINGS.CarouselSizeN",
8294
hint: "COMBAT_CAROUSEL.SETTINGS.CarouselSizeH",
@@ -86,8 +98,10 @@ export default function registerSettings() {
8698
choices: DEFAULT_CONFIG.carouselSize.choices,
8799
config: true,
88100
onChange: async s => {
89-
await ui.combatCarousel.render(true);
90-
ui.combatCarousel.element.addClass(s);
101+
if (ui.combatCarousel?.rendered) {
102+
await ui.combatCarousel.render(true);
103+
ui.combatCarousel.element.addClass(s);
104+
}
91105
}
92106
});
93107

@@ -100,7 +114,7 @@ export default function registerSettings() {
100114
choices: DEFAULT_CONFIG.imageType.choices,
101115
config: true,
102116
onChange: s => {
103-
ui.combatCarousel.render(true);
117+
if (ui.combatCarousel?.rendered) ui.combatCarousel.render(true);
104118
}
105119
});
106120

@@ -126,6 +140,18 @@ export default function registerSettings() {
126140
}
127141
});
128142

143+
game.settings.register(NAME, SETTING_KEYS.alwaysOnTop, {
144+
name: "COMBAT_CAROUSEL.SETTINGS.AlwaysOnTopN",
145+
hint: "COMBAT_CAROUSEL.SETTINGS.AlwaysOnTopH",
146+
scope: "client",
147+
type: Boolean,
148+
default: false,
149+
config: true,
150+
onChange: s => {
151+
if (ui.combatCarousel?.rendered) ui.combatCarousel.render(true);
152+
}
153+
});
154+
129155
/* -------------------------------------------------------------------------- */
130156
/* Overlay Settings */
131157
/* -------------------------------------------------------------------------- */

0 commit comments

Comments
 (0)