Skip to content

Commit

Permalink
version 2.1.27
Browse files Browse the repository at this point in the history
  • Loading branch information
p4535992 committed Jun 10, 2022
1 parent 9a4b4f9 commit 94bff29
Show file tree
Hide file tree
Showing 25 changed files with 149 additions and 17 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,10 @@ Adds a button to the Walls Menu to Shut all doors in the current scene. Also add

Changes the functionality from closing ALL doors to closing ONLY opened doors. Doors that are currently locked remain locked, and are not closed.

### [Experimental] Integration of [Combat Range Overlay](https://github.com/Nazrax/fvtt-combat-range-overlay)

[Here the documentation](./wiki/docs/combat-range-overlay.md)

# Build

## Install all packages
Expand Down Expand Up @@ -367,6 +371,7 @@ Thanks to anyone who helps me with this code! I appreciate the user community's
- [foundryvtt-stairways](https://gitlab.com/SWW13/foundryvtt-stairways) ty to [SWW13](https://gitlab.com/SWW13)
- [foundryvtt-rangefinder](https://github.com/manuelVo/foundryvtt-rangefinder/tree/master) ty to [manuelVo](https://github.com/manuelVo)
- [drag-ruler](https://github.com/manuelVo/foundryvtt-drag-ruler) ty to [manuelVo](https://github.com/manuelVo)
- [range-overlay](https://github.com/Nazrax/fvtt-combat-range-overlay) ty to [Nazrax](https://github.com/Nazrax/)

A very big thanks to [manuelVo](https://github.com/manuelVo), because i was to stupid to understand thing like measurement of Foundry by myself.

Expand Down
4 changes: 4 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

### 2.1.27

- Bug fix integration with stairway

### 2.1.26

- Bug fix
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "foundryvtt-arms-reach",
"title": "FoundryVTT Arms Reach",
"description": "Allows the GM to limit the distance that a player can interacted with a placeable object like door, journal, stairway, token, ecc..",
"version": "2.1.26",
"version": "2.1.27",
"scripts": {
"package": "gulp package",
"build": "gulp build && gulp link",
Expand Down
4 changes: 3 additions & 1 deletion src/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -225,5 +225,7 @@
"foundryvtt-arms-reach.speed-attr-path-hint": "Advanced: Set this only if you're using a System that can't autodetect token Speed",
"foundryvtt-arms-reach.info-button": "Basic Information",
"foundryvtt-arms-reach.token-speed-warning-gm": "I can't autodetect token speed; please manually set your token's speed and/or set the Speed Attribute in the module settings (and maybe open an issue to add support for your System)",
"foundryvtt-arms-reach.token-speed-warning-player": "Please manually set your token's speed (and maybe ask your GM to configure the Speed Attribute in the module settings)"
"foundryvtt-arms-reach.token-speed-warning-player": "Please manually set your token's speed (and maybe ask your GM to configure the Speed Attribute in the module settings)",
"foundryvtt-arms-reach.ignore-difficult-terrain": "Ignore difficult terrain?",
"foundryvtt-arms-reach.ignore-difficult-terrain-hint": " "
}
8 changes: 4 additions & 4 deletions src/module.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "foundryvtt-arms-reach",
"title": "FoundryVTT Arms Reach",
"description": "Allows the GM to limit the distance that a player can interacted with a placeable object like door, journal, stairway, token, ecc..",
"version": "2.1.26",
"version": "2.1.27",
"author": "Psyny, p4535992",
"type": "module",
"socket": true,
Expand Down Expand Up @@ -46,9 +46,9 @@
"manifestPlusVersion": "1.2.1",
"url": "https://github.com/p4535992/foundryvtt-arms-reach",
"manifest": "https://github.com/p4535992/foundryvtt-arms-reach/releases/latest/download/module.json",
"download": "https://github.com/p4535992/foundryvtt-arms-reach/releases/download/v2.1.26/module.zip",
"readme": "https://github.com/p4535992/foundryvtt-arms-reach/blob/v2.1.26/README.md",
"changelog": "https://github.com/p4535992/foundryvtt-arms-reach/blob/v2.1.26/changelog.md",
"download": "https://github.com/p4535992/foundryvtt-arms-reach/releases/download/v2.1.27/module.zip",
"readme": "https://github.com/p4535992/foundryvtt-arms-reach/blob/v2.1.27/README.md",
"changelog": "https://github.com/p4535992/foundryvtt-arms-reach/blob/v2.1.27/changelog.md",
"bugs": "https://github.com/p4535992/foundryvtt-arms-reach/issues",
"allowBugReporter": true,
"dependencies": [
Expand Down
9 changes: 6 additions & 3 deletions src/module/lib/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,12 @@ export function getElevationPlaceableObject(placeableObject: any): number {
? //@ts-ignore
_levels.getTokenLOSheight(placeableObject)
: base.elevation ??
base.flags['levels']?.elevation ??
base.flags['levels']?.rangeBottom ??
base.flags['wallHeight']?.wallHeightBottom ??
(base.flags
? base.flags['levels']?.elevation ??
base.flags['levels']?.rangeBottom ??
base.flags['wallHeight']?.wallHeightBottom ??
0
: 0) ??
0;
return base_elevation;
}
Expand Down
20 changes: 19 additions & 1 deletion src/module/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { registerSocket } from './socket';
import { Overlay } from './apps/range_overlay/overlay';
import { keyboard } from './apps/range_overlay/keyboard';
import { mouse } from './apps/range_overlay/mouse';
import { toggleButton, TOGGLE_BUTTON, _toggleButtonClick } from './apps/range_overlay/controls';
import { TOGGLE_BUTTON, _toggleButtonClick } from './apps/range_overlay/controls';
import { canvasTokensGet } from './apps/range_overlay/utility';
import { TokenInfo, updateLocation, updateMeasureFrom } from './apps/range_overlay/tokenInfo';

Expand Down Expand Up @@ -347,6 +347,9 @@ export const readyHooks = async () => {
// [EXPERIMENTAL] Range Overlay Integration
if (game.settings.get(CONSTANTS.MODULE_NAME, 'enableRangeOverlay')) {
Hooks.on('getSceneControlButtons', (controls: SceneControl[]) => {
if (!game.settings.get(CONSTANTS.MODULE_NAME, 'enableRangeOverlay')) {
return;
}
const tokenButton = controls.find((b) => b.name == 'token');

if (tokenButton) {
Expand Down Expand Up @@ -410,20 +413,29 @@ export const readyHooks = async () => {

// noinspection JSUnusedLocalSymbols
Hooks.on('createCombatant', (combatant, options, someId) => {
if (!game.settings.get(CONSTANTS.MODULE_NAME, 'enableRangeOverlay')) {
return;
}
const token = canvasTokensGet(combatant.token.id);
updateMeasureFrom(token, undefined);
API.combatRangeOverlay.instance.fullRefresh();
});

// noinspection JSUnusedLocalSymbols
Hooks.on('deleteCombatant', (combatant, options, someId) => {
if (!game.settings.get(CONSTANTS.MODULE_NAME, 'enableRangeOverlay')) {
return;
}
const token = canvasTokensGet(combatant.token.id);
updateMeasureFrom(token, undefined);
API.combatRangeOverlay.instance.fullRefresh();
});

// noinspection JSUnusedLocalSymbols
Hooks.on('updateCombat', (combat, turnInfo, diff, someId) => {
if (!game.settings.get(CONSTANTS.MODULE_NAME, 'enableRangeOverlay')) {
return;
}
if (combat?.previous?.tokenId) {
const token = canvasTokensGet(combat.previous.tokenId);
updateMeasureFrom(token, undefined);
Expand All @@ -433,6 +445,9 @@ export const readyHooks = async () => {

// noinspection JSUnusedLocalSymbols
Hooks.on('updateToken', (tokenDocument, updateData, options, someId) => {
if (!game.settings.get(CONSTANTS.MODULE_NAME, 'enableRangeOverlay')) {
return;
}
const tokenId = tokenDocument.id;
const realToken = <Token>canvasTokensGet(tokenId); // Get the real token
updateLocation(realToken, updateData);
Expand All @@ -443,6 +458,9 @@ export const readyHooks = async () => {
});

Hooks.on('controlToken', (token, boolFlag) => {
if (!game.settings.get(CONSTANTS.MODULE_NAME, 'enableRangeOverlay')) {
return;
}
if (boolFlag && TokenInfo.current.speed === 0 && TokenInfo.current.getSpeedFromAttributes() === 0) {
if (game.user?.isGM) {
warn(i18n(`${CONSTANTS.MODULE_NAME}.token-speed-warning-gm`), true);
Expand Down
14 changes: 7 additions & 7 deletions src/module/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ export const registerSettings = function () {
name: i18n(`${CONSTANTS.MODULE_NAME}.settingNameRangeOverlayFeature`),
hint: i18n(`${CONSTANTS.MODULE_NAME}.settingHintRangeOverlayFeature`),
scope: 'world',
config: true,
config: false,
default: false,
type: Boolean,
});
Expand Down Expand Up @@ -437,7 +437,7 @@ export const registerSettings = function () {
name: `${CONSTANTS.MODULE_NAME}.movement-alpha`,
hint: `${CONSTANTS.MODULE_NAME}.movement-alpha-hint`,
scope: 'client',
config: true,
config: false,
type: Number,
default: 0.1,
range: <any>{
Expand All @@ -454,7 +454,7 @@ export const registerSettings = function () {
name: `${CONSTANTS.MODULE_NAME}.ic_visibility`,
hint: `${CONSTANTS.MODULE_NAME}.ic_visibility-hint`,
scope: 'client',
config: true,
config: false,
type: String,
default: `never`,
choices: <any>{
Expand All @@ -471,7 +471,7 @@ export const registerSettings = function () {
name: `${CONSTANTS.MODULE_NAME}.ooc_visibility`,
hint: `${CONSTANTS.MODULE_NAME}.ooc_visibility-hint`,
scope: 'client',
config: true,
config: false,
type: String,
default: `never`,
choices: <any>{
Expand All @@ -488,7 +488,7 @@ export const registerSettings = function () {
name: `${CONSTANTS.MODULE_NAME}.ranges`,
hint: `${CONSTANTS.MODULE_NAME}.ranges-hint`,
scope: 'client',
config: true,
config: false,
type: String,
default: '5',
onChange: () => {
Expand All @@ -500,7 +500,7 @@ export const registerSettings = function () {
name: `${CONSTANTS.MODULE_NAME}.diagonals.name`,
hint: `${CONSTANTS.MODULE_NAME}.diagonals.hint`,
scope: 'world',
config: true,
config: false,
type: String,
default: 'fiveTenFive',
choices: <any>{
Expand All @@ -518,7 +518,7 @@ export const registerSettings = function () {
name: `${CONSTANTS.MODULE_NAME}.speed-attr-path`,
hint: `${CONSTANTS.MODULE_NAME}.speed-attr-path-hint`,
scope: 'world',
config: true,
config: false,
type: String,
default: '',
});
Expand Down
100 changes: 100 additions & 0 deletions wiki/docs/combat-range-overlay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
## Summary

This module is designed to quickly and efficiently answer questions such as "How far can I move this turn? What enemies can I reach in the fewest actions? How can I best navigate difficult terrain?" I wrote it because I (not to mention the rest of my group) was tired of my pulling out Rulers, Blasts, and other helpers to figure out "Can I do _this_? Hmm, no, but maybe if I do it _this_ way ... nope, that doesn't work either. What about ..."

## Basic Usage

Click ![the button](../images/the-button.png) to toggle the Overlay on and off. Once the Overlay is enabled, it should Just Work™ with little to no interaction from you. By default, it assumes your weapon has a range of 5 feet; shift-click the button to change it for your currently selected token. Normally the overlay will reread your position at the end of your combat turn; control-click the button to force the Overlay to reposition. Display preferences are available in the module's Settings page.

## Compatibility
Maps: This module relies on square tiles; I have no idea what would happen if you tried to use it on a map with hex tiles, but I don't think it would go well.

Systems: My table plays Pathfinder 2E, and that's all I've tested it with.
It turns out that every system stores its token/actor move speeds in a different spot,
so out of the box speed autodetection will only work with Pathfinder 1, Pathfinder 2E, DND3.5,
and DND5E. If you're playing with a different system, you'll need to do some
[extra configuration](#advanced-setting-the-speed-attribute-path). Also, I believe other systems
treat diagonals differently, so there's a (GM-only) setting telling the module how to count
diagonal movement.

Modules: This module requires lib-wrapper and supports the Enhanced Terrain Layer.

## Understanding the Overlay

![legend](../images/legend.jpg)

The overlay in this image assumes a movement speed of 15ft/action and a weapon range of 10ft.

1. Tiles tinted blue can be reached in a single action.
2. Tiles tinted yellow can be reached in 2 actions.
3. Enemies circled in white can be attacked without moving.
4. Enemies circled in blue can be attacked in a single move.
5. Enemies circled in yellow can be attacked with 2 moves.
6. Enemies circled in red require 3 or more movements to attack.
7. All tokens (other than the selected token) in combat are annotated with their initiative order relative to the current token.
8. The selected token is annotated with the currently selected weapon range.

![single target](../images/single-target.jpg)

If a target is selected, tiles in your movement range _and_ in range of the target will be highlighted in white, and only tiles on the shortest path to the highlighted squares will remain tinted.
If multiple targets are selected, only tiles in range of _all_ targeted enemies will be highlighted. If there's no way to hit all targeted enemies at once, the Overlay will display a warning and act as if no enemies are targeted.

## Sample Use-cases

The Overlay is useful no matter what kind of character you're playing as:

### Melee

![](../images/melle1.jpg)
Suppose you're trying to decide between these two enemies.

![](../images/melle2.jpg)
Both enemies are obstructed - one by difficult terrain, one by walls - so a straight ruler won't help you.

![](../images/melle3.jpg)
You'll need to use waypoints to get the true movement distances.

![](../images/melle4.jpg)
Or you can use the Overlay to instantly see how many movement actions it'll take to attack each enemy.

### Archery

![](../images/archery1.jpg)
You want to attack this enemy, and you'd like to get _just_ close enough to attack him without his being able to close the distance and attack you on his turn.

![](../images/archery2.jpg)
You drop a Blast on his position and then move to a tile on the very edge of the Blast (of course, working with Blasts takes a lot of control palette switching, clicking, dragging, deleting ... it's kind of a pain).

![](../images/archery3.jpg)
Or you can use the Overlay to see where you can move to that's inside your attack range and move to the position that's nearest you.

### Magic

![](../images/magic1.jpg)
You want to cast Electric Arc (a 2 action, 2 target, 30ft range spell) on these two enemies. Where can you hit them both from? Are they close enough for you to hit them both? Can you reach a good spot in only one action so you'll have the two remaining actions to cast the spell?

![](../images/magic2.jpg)
You could drop _two_ Blasts and then measure your distance to the overlapping tiles (with waypoints, of course - moving straight through that difficult terrain would be too much).

![](../images/magic3.jpg)
Or you can use the Overlay to see where you can attack them both from and how far away the good spots are.

### Tactician

![](../images/tactician1.jpg)
You're pretty sure you can kill any of these enemies on your turn, and you'd like to kill one that'll go before your teammate to reduce how many enemies there are to attack him (or you). Unfortunately, while the Combat Tracker shows initiative order it doesn't take positioning into account, and trying to figure out which entry in the Combat Tracker corresponds to combatant tokens can be a pain.

![](../images/tactician2.jpg)
Or you can use the Overlay to see who's close to you _and_ going before your teammate.

## Advanced: Setting the speed attribute path
If you're using an unsupported System, you'll need to set the speed attribute path in
the module settings. Here's how to do it:
1) Select a token
1) Open your browser's dev tools and switch to the Javascript console
1) Type in `canvas.tokens.controlled[0].actor.data` and press Enter
1) Expand the result, then keep expanding children until you find the movement speed. Take note of each child
you expand
* For instance, with Pathfinder 2E, you expand `data`, `attributes`, `speed`, and find the speed in `total` ![](../images/object_flags.png)
1) Join these names with periods to come up with your attribute path
* For Pathfinder 2E, this would be `data.attributes.speed.total`
Binary file added wiki/images/archery1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added wiki/images/archery2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added wiki/images/archery3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added wiki/images/legend.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added wiki/images/magic1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added wiki/images/magic2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added wiki/images/magic3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added wiki/images/melle1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added wiki/images/melle2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added wiki/images/melle3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added wiki/images/melle4.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added wiki/images/object_flags.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added wiki/images/single-target.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added wiki/images/tactician1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added wiki/images/tactician2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added wiki/images/the-button.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 94bff29

Please sign in to comment.