PDA

View Full Version : 5E - Token Height Indicator



Pages : [1] 2 3

GKEnialb
February 28th, 2021, 06:06
With the FG Ruleset Updates 2023-02, token heights are now part of the base FGU. I've delisted this extension to avoid any conflicts or confusion. Thanks for all the support the last couple of years. If anyone is interested in code and/or wants to steal any part of it, you can find it on GitHub (https://github.com/GoodKingEnialb/Token-Height-Indicator).




This extension allows the height of each token to be set / displayed by holding down the alt key and using the scroll wheel. The token orientation is changed with shift and scroll wheel and the token scale is changed with control and scroll wheel. The height can only be set by tokens in the combat tracker.

Ranges (both the range arrow and via the getDistanceBetweenTokens call for use by other extensions) are updated accordingly.

This is available on the Forge (https://forge.fantasygrounds.com/shop/items/67/view).

Screenshot
45758

License

This work is Public Domain - feel free to distribute / copy / modify / incorporate as you wish.

Methods for range
My goal is to the mirror the spirit of each style in the rulesets, not necessarily to provide the most accurate result (which will always be raw). As such:

5E Standard: 2D formula is max(x delta, y delta). My formula is max(x delta, y delta, z delta)

5E Variant / most other rulesets: "Variant Diagonal Style" option to account for two schools of thought on whether the distance between a token at 0,0,0 and one at 5,5,5 is 5ft or 10ft. The only difference between the two options is when all three deltas are the same.

"Long": 2D formula is longer delta + 1/2 shorter delta. My formula is longest delta + 1/2 other two deltas.
"Short": 2D formula is longer delta + 1/2 shorter delta. My formula is longest delta + 1/2 middle delta (ignoring smallest delta).

5E Raw Variant / "Raw Distance" option on maps for other rulesets: 2D formula is sqrt(x2+y2). My formula is sqrt(x2+y2+z2).

There are lots of ways to make 5E Standard / variant measurements more "accurate", but that goes against the spirit of those rulesets. If you want to be entirely accurate, then you should use the raw measurements.

Note that Token Height changes squares into cubes and the bottom of the cube is what the height value represents. So a Medium creature with height 0 is assumed to extend from 0' to 5'. As with FGU's distance equations, the starting point for the calculation is in the middle of the square closest to the target, so the distance between a Medium creature and one directly above it will start at 2.5' and a Huge creature (15') with height 0 will start at 12.5' (assuming 5' cubes). If they were moved 10' into the air, the calculation would start at 12.5' and 22.5', respectively.

Shape support (for use by other extensions)

TokenHeight.getTokensWithinShape(originToken, shape, distance, height, width, azimuthalAngle, polarAngle)
Image.getTokensWithinShapeFromToken(originItem, shape, distance, height, width, azimuthalAngle, polarAngle)
Image.getTokensWithinShape(originX, originY, originZ, shape, distance, height, width, azimuthalAngle, polarAngle)

Get all tokens within a shape (including the origin token, if any). Any token with any part of its containing cube will be returned. I know there is a lot of debate and variations on how much of a token needs to overlap for a given shape type. As such, I'm returning all, as it's easier to remove tokens you don't want than to add...

The parameters for each type of shape are:

All:

originX, originY, originZ - the coordinates of the center / origin of the shape
shape - "sphere", "cube", "cylinder", "line", "cone"

sphere:

distance = radius of the sphere

cube:

distance = length of each side of the cube

cylinder:

distance = radius of the sphere
height = height of the cylinder

line:

distance = length of the line
width = width of the line (half on each side of the line in all directions)
azimuthalAngle = angle of the line leaving the origin in the X/Y plane in degrees. 0 = north, 90 = east
polarAngle = angle of the line leaving the origin in the X/Z plane in degrees. 0 = flat, 90 = straight up

cone:

distance = length of the cone
width = angle of the cone aperture (53 in 5E, 90 in 3.5/PFRPG)
azimuthalAngle = angle of the center of the cone leaving the origin in the X/Y plane in degrees. 0 = north, 90 = east
polarAngle = angle of the center of the cone leaving the origin in the X/Z plane in degrees. 0 = flat, 90 = straight up





Known Bugs / Future plans
- This is for FGU only; it will not work with FGC
- Tested with 5E / 4E / 3.5E / Pathfinder 1&2 / Starfinder / MoreCore; others should work but have not been tested
- Height of an NPC will get reset when taking / removing control of that NPC with GM Assistant
- You will see a slight shift in the token as you change heights. This is to work around a change in FGU 4.3.1 and will not impact the distance calculations.

Version History (most recent)
6.0: Major performance improvements by moving logic from combat tracker nodes to image tokens with help from silentruin, MeAndUnique, and Saagael
6.1: Re-added the code accidentally deleted that made AuraEffects recalculate the auras on a height change
6.2: Removed warning for tokens on map that aren't in combat tracker or are in combat tracker but have no associated space
6.3: Fixed error in Token.getTokensWithinDistance
6.4: Fixed error when changing options
6.5: Fixed issues with D&D 4E
6.6: Workaround for sometimes tokens losing their names, causing them to always share the same height value

nephranka
February 28th, 2021, 12:50
Thank you. I have been looking for a replacement for the 5e enhancer ext. I use it only to do height, remove actors and effects (since it is broken for many other functions) but I have been getting nervous that some future update will break even these. It is an old project that has been orphaned. This is the biggest piece for me and now I can move on!

GKEnialb
February 28th, 2021, 17:17
There are definitely good replacement apps for those other functions, so glad to hear this completes what you need. My goal was to make this as minimalistic as possible so updates or other extensions won't break it (fingers crossed).

RedmondStache
February 28th, 2021, 18:38
I'd love to use this extension, but it seems that enabling this extension makes it so that token scaling is done with the scroll wheel alone, without any modifier keys required, and that's not something I want to happen.

I don't know if that's intended functionality or caused by some sort of interaction with another extension I've got, but I do know that as long as it's the case I cannot use this one.

nephranka
February 28th, 2021, 23:38
Yes. I noticed that as well. If we can lock that would be helpful. Also, can you make it visible to the players? Mine could not see the height indicator.

GKEnialb
March 1st, 2021, 00:18
I will look into both of those (locking with cntrl-scroll to change scale and making visible to the players)

GKEnialb
March 1st, 2021, 03:37
And I've updated to address both. Thanks for the feedback!

spoonhead
March 1st, 2021, 05:21
Does the height affect range? Also, I would love it if the players could change their height, but not sure if possible if the token is locked.

nephranka
March 1st, 2021, 11:27
Looks like the changes are working. I would 2nd players being able to change height.

I know the 5e enhancer factor height into the range calculation but I am not sure if that would play nice with the other range exts that handle feats, range in melee and long vs normal range modifiers. If not then that could be a project to complete because many of us would not give up those automations for a range that included height. It would be nice to have though!

Thank you for the updates!

MrDDT
March 1st, 2021, 23:14
Looks like the changes are working. I would 2nd players being able to change height.

I know the 5e enhancer factor height into the range calculation but I am not sure if that would play nice with the other range exts that handle feats, range in melee and long vs normal range modifiers. If not then that could be a project to complete because many of us would not give up those automations for a range that included height. It would be nice to have though!

Thank you for the updates!

This is why I still have to use the one from Enhancer sadly. Pulling the Height.ext out of it works just fine to do what this ext is doing also. However, would be nice if we could get that range checking in there. Maybe we are just getting greedy on what we want our exts to do haha.

GKEnialb
March 2nd, 2021, 03:27
Okay, I added the ability for the players to change the height of their token if enabled via the options. I'm going to stay away from range, though - I intentionally want to keep this as small as possible and also want to avoid conflicts with other extensions. Might be able to be convinced to tackle it in the future, though... :)

Noelus
March 4th, 2021, 22:40
I wonder if there is any possibility of taking another look at your code. As it stands the ext conflicts with Map Parcel extension in that Ctrl plus mouse wheel only reduces the size of parcel tokens but does not increase them.

GKEnialb
March 5th, 2021, 01:30
Unfortunately I don't own Map Parcel and it's not free. For cntrl-wheel, all I do is call the base cntrl-wheel code, so there's no difference in increasing or decreasing that I do. SilentRuin is free to modify Map Parcel (or incorporate this extension into Map Parcel), otherwise the best I could do is provide an option to turn off cntrl-wheel, but I'm guessing that's not what you're looking for.

realmsoff
March 5th, 2021, 12:45
I can reproduce the Ctrl-plus mouse wheel behaviour mentioned by Noelus, but without using the Map Parcel extension! The difference is that sofar it only affects tokens that are based on a image file with dimensions that don't form a square...

GKEnialb
March 5th, 2021, 16:31
Interesting. I'll take a look at that.

And I have been able to reproduce. I'll take a look at what they're doing in the core rules.

GKEnialb
March 5th, 2021, 19:29
v1.3 is available, which works for rectangular tokens. There was a bit of fudging with the math, so let me know if you have tokens that still have an issue. Hopefully this'll work fine with Map Parcel as well.

nephranka
March 19th, 2021, 14:25
Not sure if this is expected behavior but, players can not adjust the height until the GM sets it first. Then they can not get back to zero height. It only allows them -5ft or 5ft.

The test is have a player try to adjust height before the GM does.

GKEnialb
March 19th, 2021, 17:31
That's not expected behavior - I'll check it out.

GKEnialb
March 19th, 2021, 21:18
Not sure if this is expected behavior but, players can not adjust the height until the GM sets it first. Then they can not get back to zero height. It only allows them -5ft or 5ft.

The test is have a player try to adjust height before the GM does.


Version 1.4 uploaded which fixes both of these issues. Thanks for pointing them out!

nephranka
March 20th, 2021, 02:57
All resolved. Thanks!

nephranka
March 22nd, 2021, 11:23
Looks like there is another error. When the GM moves a token to an unshared map the player gets the following error:
[3/22/2021 6:16:19 AM] [ERROR] Handler error: [string "scripts/token_height_indication.lua"]:133: attempt to index local 'ctToken' (a nil value)

Logs:
[3/22/2021 6:15:39 AM] RULESET: Dungeons and Dragons (5E) ruleset (v2021-03-09) for Fantasy Grounds
Copyright 2021 Smiteworks USA, LLC
[3/22/2021 6:15:39 AM] RULESET: Core RPG ruleset (v2021-03-16) for Fantasy Grounds
Copyright 2021 Smiteworks USA, LLC
[3/22/2021 6:15:39 AM] EXTENSION: 5E Height Indication by GKEnialb
[3/22/2021 6:15:39 AM] EXTENSION: Roboto Font Extension v1.1
[3/22/2021 6:15:39 AM] MEASURE: LOAD - PART 2 - 2.338483
[3/22/2021 6:15:39 AM] NETWORK SEND FILE REQUEST: BattleMap_Cave01.jpg@FG Battle Maps
[3/22/2021 6:15:39 AM] NETWORK RECV FILE REQUEST: BattleMap_Cave01.jpg@FG Battle Maps
[3/22/2021 6:15:40 AM] NETWORK SEND FILE REQUEST: campaign/portraits/id-00001
[3/22/2021 6:15:40 AM] NETWORK RECV FILE REQUEST: campaign/portraits/id-00001
[3/22/2021 6:15:54 AM] [WARNING] Frame tabs contains out-of-range values in BottomLeft.
[3/22/2021 6:16:09 AM] [WARNING] buttoncontrol: Could not find normal icon () in control (toggle_unmask) in class (imagewindow_toolbar)
[3/22/2021 6:16:19 AM] [WARNING] buttoncontrol: Could not find normal icon () in control (toggle_unmask) in class (imagewindow_toolbar)
[3/22/2021 6:16:19 AM] [ERROR] Handler error: [string "scripts/token_height_indication.lua"]:133: attempt to index local 'ctToken' (a nil value)
[3/22/2021 6:16:19 AM] [ERROR] Handler error: [string "scripts/token_height_indication.lua"]:133: attempt to index local 'ctToken' (a nil value)
[3/22/2021 6:16:19 AM] [ERROR] Handler error: [string "scripts/token_height_indication.lua"]:133: attempt to index local 'ctToken' (a nil value)

screenshot attached.

bmos
March 22nd, 2021, 13:48
This already existed:
https://www.fantasygrounds.com/forums/showthread.php?51005-Extension-Height-label

Perhaps you two can work together to make the two better?

anathemort
March 22nd, 2021, 17:07
Looks like there is another error. When the GM moves a token to an unshared map the player gets the following error:
[3/22/2021 6:16:19 AM] [ERROR] Handler error: [string "scripts/token_height_indication.lua"]:133: attempt to index local 'ctToken' (a nil value)

This is fixed in 1.5

nephranka
March 22nd, 2021, 18:30
Thank you. I missed that update!

GKEnialb
March 22nd, 2021, 22:53
Yeah, sorry about that - I noticed that same issue shortly after I created 1.4 and updated the first post but should have also noted it down here...

Mazzar
March 24th, 2021, 20:52
Thank you for this extension. I also used the 5E Enhancer mostly for the height feature. The one thing that the original Combat Enhancer did was that it adjusted the target distance based on the height. It actually took the hypotenuse and replaced the target distance with that. Styrmir was going to fix/add this in his next version of 5E Enhancer but he stopped working on the extension before then.

Would it be possible to do this?

GKEnialb
March 25th, 2021, 01:45
I intentionally minimized the functionality to ensure it didn't run into conflicts with other extensions or be broken with FGU updates, but I can take a look to see if there's a way to safely do this. One question I have is whether you're using an alternate diagonal option or the core 5E rules - if the latter, I would have the range reflect the maximum of the horizontal distance and height (same as the range arrow now, just flipped 90 degrees). If I update the range arrow, I will reflect all the diagonal options, though.

Mazzar
March 25th, 2021, 02:03
I intentionally minimized the functionality to ensure it didn't run into conflicts with other extensions or be broken with FGU updates, but I can take a look to see if there's a way to safely do this. One question I have is whether you're using an alternate diagonal option or the core 5E rules - if the latter, I would have the range reflect the maximum of the horizontal distance and height (same as the range arrow now, just flipped 90 degrees). If I update the range arrow, I will reflect all the diagonal options, though.


I do use the alternating rule but I am not married to it. I had once suggested to Styrmir that he didn’t necessarily have to recreate the target line to overwrite the distance and maybe in parenthesis next to it just add the altered distance. The best case scenario was to overwrite it if possible but ultimately I just wanted something to show the new calculated distance. At the time he was concerned with smiteworks changing the target arrow (which they did) but now I assume they have the permanent arrow now.

Thank you!

Naurthoron
March 25th, 2021, 12:20
Having recalculated distance taking height into consideration for 5E satndard rules would be really nice indeed!

GKEnialb
March 29th, 2021, 04:08
I have a version (1.6) to take height into account for range arrows (for all three types of diagonals). Unfortunately it's not as straight-forward as other mods as you can't call the original arrow code, so please let me know if you see anything odd. A couple of other notes:
- Pointers for variant diagonals can be off by 5' due to some rounding issues
- The range arrows don't update automatically when changing the height until the token loses focus (just move the pointer off of the token and everything will update)

nephranka
March 29th, 2021, 11:44
I have a version (1.6) to take height into account for range arrows (for all three types of diagonals). Unfortunately it's not as straight-forward as other mods as you can't call the original arrow code, so please let me know if you see anything odd. A couple of other notes:
- Pointers for variant diagonals can be off by 5' due to some rounding issues
- The range arrows don't update automatically when changing the height until the token loses focus (just move the pointer off of the token and everything will update)

Working fine here. Looks to be calculating and updated as expected. I too like the range calculations with height added.

There is one issue for me. I use an ext to calculate DIS in melee and at long range/out of range for ranged weapons/spell attacks:
https://www.dmsguild.com/product/314487/Fantasy-Grounds-Automatic-Flanking-and-Range

At this point I can set a height to 50ft and put the token 5ft away from the target and I get DIS on the attack. Clearly, it is not seeing the new range. Similarly, if I set it to 500 ft height, I do not get DIS being at long range nor am I out of range if I set it to 1000ft.

It would be great to get these two to work together.

GKEnialb
March 29th, 2021, 17:40
Yeah, there is no height concept in the core ruleset and the range arrows are just text (no underlying calculations are update), so there's nothing I can do on my end. My height value is visible to other extensions, though, so they could integrate in that direction if they want. Those two do great work, so I'd love for them to integrate (though I believe Kent's super swamped at the moment) - I'll send Kent a note on Discord to see if he's interested, but that's the best I can do.

nephranka
March 29th, 2021, 18:11
No worries. Just reporting back the test results. Knowing it is strictly informational allows me to use it with modifications. I appreciate all the work. Thanks!

GKEnialb
March 30th, 2021, 01:48
Thanks. I did send a note to Kent on Discord - hopefully he'll be interested. The calculations for the range are in image.lua if you're interested.

nephranka
March 30th, 2021, 02:13
Thanks! I hope it works out. This is one that would be cool to get working.

This and a auto combat adjusted invisibility/see invis/truesight/blindsight/blur. One can hope someday!

Kelrugem
March 30th, 2021, 21:04
This already existed:
https://www.fantasygrounds.com/forums/showthread.php?51005-Extension-Height-label

Perhaps you two can work together to make the two better?

Oh, sorry, didn't see your post until now :) (checking the extension thread too rarely, I guess :D and when, then I skim a lot)

Yes, sure, if GKEnialb wants and it's okay for them, I am certainly available :) Just not so much time right now, and maybe the GPL license is a bit too much in my version; but when I have finally time again, then I normally wanted to rewrite the extension for getting rid of the original author's license :)

GKEnialb
March 31st, 2021, 01:10
Oh, sorry, didn't see your post until now :) (checking the extension thread too rarely, I guess :D and when, then I skim a lot)

Yes, sure, if GKEnialb wants and it's okay for them, I am certainly available :) Just not so much time right now, and maybe the GPL license is a bit too much in my version; but when I have finally time again, then I normally wanted to rewrite the extension for getting rid of the original author's license :)

Sounds good to me. Just let me know when you have some time.

Kelrugem
March 31st, 2021, 01:25
Sounds good to me. Just let me know when you have some time.

Cool, I'll do :)

badgr
April 2nd, 2021, 20:32
- Range arrows won't update after changing height until you move off of the token.

I've been working on my own version of this functionality for my own players/fellow GMs in a Discord group of my friends, and the solution I've gone with was to move the functionality of the height update to the "Size & Space" section of the GM's combat tracker and put it there instead. Then I set up DB listeners on this and had it go through all CT entries that were visible, get its/their targets (this isn't an issue, because currently it only runs from Host side, not client) and then iterate through its targets and reapply them again.

Fairly simple checks and code, and doesn't cause any issues on testing so far. This might be something you can do with the DB.addHandler for changes in the height values. That way you don't have to re-select or re-target to update the range on the measure pointers.

GKEnialb
April 2nd, 2021, 21:29
Thanks for the suggestion. Can the players change their own height with that approach? That was an early request for this extension.

badgr
April 2nd, 2021, 22:34
Currently mine doesn't, but it would require a little bit of reworking of the code so that on player change, it would simply update their own targeting based on tokens they're currently targeting and provided those targets are still visible to them.

GKEnialb
April 2nd, 2021, 22:41
I may be able to take a hybrid of the two approaches or there may be a way to kick the pointer logic to have it redraw without the token losing / regaining focus.

eporrini
April 8th, 2021, 11:46
Is this using the actual “real life formula” for calculating distance that includes height or simply adding any height on as an additional 5’?

GKEnialb
April 8th, 2021, 15:29
Is this using the actual “real life formula” for calculating distance that includes height or simply adding any height on as an additional 5’?

It depends on what setting you have selected for diagonals. For standard, the range is the max of the three dimensions (just as the horizontal range is the max of the two dimensions). For alternate (with the diagonals being counted as 1 for first square and 2 for second), you get full range in the longest dimension and half range on the other two dimensions. For raw, you get the real life formula (actual distance between 2 points in 3 dimensions, with 0.1 foot accuracy).

eporrini
April 8th, 2021, 15:47
It depends on what setting you have selected for diagonals. For standard, the range is the max of the three dimensions (just as the horizontal range is the max of the two dimensions). For alternate (with the diagonals being counted as 1 for first square and 2 for second), you get full range in the longest dimension and half range on the other two dimensions. For raw, you get the real life formula (actual distance between 2 points in 3 dimensions, with 0.1 foot accuracy).

Thanks for the detailed response. I enjoy using this extension as do my players.

GKEnialb
April 8th, 2021, 17:20
No worries and thanks for the feedback!

EBF Blackhawk
April 9th, 2021, 00:53
New to extensions and running games in FGC, I am running only this extension and if I try to adjust things I get an error.
Script Error: [string "scripts/token_height_indication.lua"]:104: attempt to call field 'getOwner' (a nil value)

Any advice (or additional info I can provide)?

GKEnialb
April 9th, 2021, 03:23
New to extensions and running games in FGC, I am running only this extension and if I try to adjust things I get an error.
Script Error: [string "scripts/token_height_indication.lua"]:104: attempt to call field 'getOwner' (a nil value)

Any advice (or additional info I can provide)?

Sorry to hear that. Did you add the token to the map by dragging from the combat tracker? Was the DM adjusting the token or was it a player? I'll update to prevent the error in any case - just trying to see how it got in that state.

GKEnialb
April 9th, 2021, 03:56
Created 1.7 - you can download the new version it from the first post. It'll prevent that error showing up, but it'd still be good to figure out how you got there in the first place.

EBF Blackhawk
April 9th, 2021, 04:07
Sorry to hear that. Did you add the token to the map by dragging from the combat tracker? Was the DM adjusting the token or was it a player? I'll update to prevent the error in any case - just trying to see how it got in that state.

Running Undermountain, I added tokens from a prebuilt encounter.
Should I re-add the tokens from the combat tracker to test?

I loaded the campaign and no players attached. Just solo testing.

EBF Blackhawk
April 9th, 2021, 04:44
So apparently I will get to be the problem child.
Upgraded to 1.7 and the old error is gone, tokens show height as expected.
Now once I have a player token target a monster and highlight over to check distance I get a new error.

Script Error: [string "campaign/scripts/image.lua"]:7: attempt to call global 'getDistanceBaseUnits' (a nil value)

Let me know any tests you want me to try, happy to test.

*edit.
Did an additional test by deleting my ..\AppData\Roaming\Fantasy Grounds folder and redownloading everything in case of bad files.
Created a new campaign using the DMG and Monster manual only and tested and still receive the error when checking distance.

GKEnialb
April 9th, 2021, 17:13
Good to be a problem child - get to find all the bugs! Can you confirm which ruleset you're using and that you have the latest FGU build? Is the grid set for the map?

I did make another fix (kept it at 1.7, so grab it again) which should prevent the error, but will return an empty range if it hits it - it can't calculate the range as the built-in call to get the units isn't visible to you for some reason. Hopefully it's a spurious case and it'll still work for you in general.

EBF Blackhawk
April 9th, 2021, 23:34
That may be the issue, I am using FGC, not FGU for my game still. Still nervous about FGU performance with LOS in large rooms.

Tested with the latest. No more error, but the distance does not show on the target arrow.

If your intent was just for FGU and not FGC, we can call it good and I will keep this bookmarked for when i upgrade to FGU.

GKEnialb
April 9th, 2021, 23:39
Yeah, that'll do it - I'm guessing that some of the calls I'm making don't exist in FGC. I'll make a note of that on the first post.

Jinashi
April 10th, 2021, 11:33
The targeting arrow does not seem to take height into account.
I am on FGU (channel: Test) with only the Height Indicator 1.7 extension

45610

GKEnialb
April 10th, 2021, 17:38
Interesting - same setup is working fine for me in the stable channel.

45620

I don't really want to spend much time in the test channel trying to fix something, as there's no guarantee everything will move forward. If I can recreate it on the stable channel, I'd definitely be happy to investigate. A few questions to help with that:


- Do both tokens appear in the combat tracker?
- If you target the medium creature with the large creature, does the range also show as 20'?
- Is the Diagonal Distance option set to standard?
- If you change the height on the large creature, does the range change?

Jinashi
April 10th, 2021, 21:13
- Yes
- Yes
- Yes
- No

45628

GKEnialb
April 10th, 2021, 21:21
Thanks. All that should be fine, so it's possible something changed on the test channel. Once those changes make it over to the main channel, I'll be able to fix.

badgr
April 11th, 2021, 04:30
Have just jumped into the Test branch of FGU to take a look, and it seems to be updating just fine on my end.

45631
45632

What I have noticed is that the range indicators update just fine when the token is the actively selected one, while the issues that you previously mentioned (that I last commented on) only occurs when the token isn't selected.

I'll be tinkering around with my own extensions here, so if I figure anything out I'll come back and share. Otherwise, looks like the issues that Jinashi is having is rather specific. This was tested on v1.7

Jinashi
April 11th, 2021, 12:05
I have the same problem in the stable version. It's really strange, I must be doing something wrong
45641

GKEnialb
April 11th, 2021, 16:50
@Jinashi, I've been able to recreate with that same map - looking into it now.


@badgr, thanks for investigating as well.

GKEnialb
April 11th, 2021, 18:31
Okay, found the issue - the grid needs to be set for this extension to work and it's not set by default on the map you were using. I'm actually surprised the range worked at all, as it uses the grid in the range calculation. If you right click on the map, select Layers, you can turn on the grid and drag it to match the size of the squares of the map (and if you unlock the map itself in the upper right, the right-most icon which appears allows you to shift the grid and gives you a little better control). I'll see if I can ignore the grid setting altogether so it's not necessary (but it's good in general to have the grid on).

GKEnialb
April 11th, 2021, 23:02
Version 1.8 created to still provide range updates for height if the grid is not active. Note that this will still use the grid settings of the map, so the behavior may seem inconsistent if the grid is off but the underlying grid settings don't match the visual squares on the map. I also put in a fix to always update the range when the height changes without requiring moving the pointer off of the token and back.

Mazzar
April 12th, 2021, 00:56
I am using the latest version of the extension and it seems the range is just matching the height. So if I have a target that is 20 feet away and I am 30 feet in the air, the target distance should be a little 33.16 feet (if you round down, then 33 feet). I guess you are rounding to the nearest 5 foot. I am thinking that if anything it should probably round up if it is less than a 5 foot increment. The reason is that you may have a range on a particular weapon or spell. If you round down then the range will be allowed. In the example above, if I have a weapon or spell range of 30 feet, I am 30 feet in the air and the target is laterally 20 feet away, the actual range is a little over 30 feet and should not be allowed. Rounding down will allow it.

Any way to round up or display the closest whole number?

GKEnialb
April 12th, 2021, 01:24
It depends on what setting you have selected for diagonals. For standard, the range is the max of the three dimensions (just as the horizontal range is the max of the two dimensions). For alternate (with the diagonals being counted as 1 for first square and 2 for second), you get full range in the longest dimension and half range on the other two dimensions. For raw, you get the real life formula (actual distance between 2 points in 3 dimensions, with 0.1 foot accuracy).

So let's say you're on standard measurements in 2D space - 20' horizontal and 30' vertical is exactly 30'. 3D space is no different in the calculations. If you want that accuracy, use raw diagonals instead.

Mazzar
April 12th, 2021, 02:08
It depends on what setting you have selected for diagonals. For standard, the range is the max of the three dimensions (just as the horizontal range is the max of the two dimensions). For alternate (with the diagonals being counted as 1 for first square and 2 for second), you get full range in the longest dimension and half range on the other two dimensions. For raw, you get the real life formula (actual distance between 2 points in 3 dimensions, with 0.1 foot accuracy).

So let's say you're on standard measurements in 2D space - 20' horizontal and 30' vertical is exactly 30'. 3D space is no different in the calculations. If you want that accuracy, use raw diagonals instead.

Ok. I see how it works.. I didn't even see that it had a Raw setting. Thank you!

GKEnialb
April 12th, 2021, 02:20
No worries - hard to keep track of all the options FG provides. :)

Finsteel
April 12th, 2021, 21:08
Thank you for all your effort with this extension!

However I think something with the 1.8 update now conflicts with bmos' 5E - Aura Effects extension (v 0.6). FGU just freezes with not responding state when an aura effect moves into range to affect someone. Aura Effects seem to work when I turn height indicator off. Both extensions worked fine together with previous version though.

nephranka
April 13th, 2021, 00:46
Thank you for all your effort with this extension!

However I think something with the 1.8 update now conflicts with bmos' 5E - Aura Effects extension (v 0.6). FGU just freezes with not responding state when an aura effect moves into range to affect someone. Aura Effects seem to work when I turn height indicator off. Both extensions worked fine together with previous version though.

I can confirm. The systems just becomes unresponsive and freezes.

It is working with 1.6. I did not get a chance to check 1.7

GKEnialb
April 13th, 2021, 01:41
Thanks - I'll take a look. I use that extension as well, but I turn off all other extensions when I'm trying to recreate issues with mine. Guess I should have turned them all back on again... ;)

GKEnialb
April 13th, 2021, 01:59
Should be fixed now with v1.9. Thanks for reporting!

nephranka
April 13th, 2021, 02:18
Tested with 1.9 and working with auras and with or without the grid.

It is funny to watch the CPU kick in as I adjust the height!

GKEnialb
April 13th, 2021, 02:34
Thanks for checking it out. I think I know why the CPU is kicking in with both extensions loaded - hopefully it only happens when adjusting height when there are auras around. It comes from the trick I used to force redrawing the range arrows. I'll try to figure out a more clever way of doing that, but hopefully it works okay for now.

nephranka
April 13th, 2021, 02:54
Totally fine! I just thought it was interesting. I have been working on chasing down a lag problem in another post, so I have been watching the computer stats and I saw it happen.

GKEnialb
April 13th, 2021, 04:26
Thanks to bmos for suggesting (and showing me how) to override a function that would allow other extensions to automatically get their range updated from this extension, v1.10 has been uploaded. Now nifty things will happen like his Aura Effects will activate / deactivate based upon the height.

nephranka
April 13th, 2021, 10:56
Confirmed to be working. I like how it works with auras now, very cool. I still have to adjust for ranged attacks in melee but it is worth it for the other functions this ext gives.

Thanks!

bmos
April 13th, 2021, 14:47
I think the diagonal range calculation in this might not be correct. All squares surrounding a creature should be 5ft away.

Basic 5E ruleset:
45701

This extension:
45702

Threatened squares:

You threaten all squares into which you can make a melee attack, even when it is not your action. Generally, that means everything in all squares adjacent to your space (including diagonally). An enemy that takes certain actions while in a threatened square provokes an attack of opportunity from you. If you’re unarmed, you don’t normally threaten any squares and thus can’t make attacks of opportunity.
Reach Weapons:

Most creatures of Medium or smaller size have a reach of only 5 feet. This means that they can make melee attacks only against creatures up to 5 feet (1 square) away. However, Small and Medium creatures wielding reach weapons threaten more squares than a typical creature. In addition, most creatures larger than Medium have a natural reach of 10 feet or more.

Also I have gotten this working in PFRPG and 3.5E (perhaps others but have not tested).
I'll pass that along (pretty minor change) once the numbers work (due to this issue).

GKEnialb
April 13th, 2021, 20:04
Thanks - I'll take a look. FG does some strange things with creatures larger than medium, so I'm guessing it's related.

GKEnialb
April 15th, 2021, 04:18
Version 1.11 has been uploaded, which matches the range of the base FGU for variant diagonals (already matched for standard and raw). I tried a bunch of cases and they all matched, but it wasn't exhaustive, so if you find a difference, let me know.

Finsteel
April 15th, 2021, 17:49
Here is a screenshot of what I get now for ranges with variant rule. (Version 1.11 Token Height extension)

- Distance to diagonally adjacent square is correctly 5'.
- Distance to two consequtive diagonals is also correctly 15' (5' for the first plus 10' for the second diagonal)
- Target at 'knight's move' distance seems to be 15' away. I think it should be 10' with variant rules. (5' for diagonal plus 5' to linearily adjacent square)
- However if you move the target half a square further away the distance drops to 10'. (the dragonborn token in the screenshot)
45767

GKEnialb
April 16th, 2021, 03:18
Thanks. Back to the drawing board. :( I agree the three on the left, from top to bottom, should be 15', 10', 15'.

GKEnialb
April 16th, 2021, 04:44
I think I fixed the variant diagonals for real this time, including for half squares. Fingers crossed.

Additionally, bmos made updates to allow this to work with 3.5 and Pathfinder, so I've updated to rev to 2.0 and changed the name of the extension (so delete the old one from the extensions directory when dropping this one in).

kevininrussia
April 16th, 2021, 06:46
I got this to work with 4e by changing two lines:

nHeight = nHeight + (1 * notches)
widget.setText(nHeight .. ' sq')

Where is this RAW setting? As squares =1 the RAW setting will be more noticeable on distances.

bmos
April 16th, 2021, 18:21
It's a Unity-only 5E-only setting.

Raw ( Interface.setDistanceDiagMult("*") ):
https://media.discordapp.net/attachments/832379716229005312/832663070617894962/unknown.png?width=900&height=969

Variant ( Interface.setDistanceDiagMult(1.5) ):
https://media.discordapp.net/attachments/832379716229005312/832663372444467220/unknown.png

Standard ( Interface.setDistanceDiagMult(1) ):
https://media.discordapp.net/attachments/832379716229005312/832663256517836830/unknown.png?width=900&height=882

Kelrugem
April 16th, 2021, 18:23
There is a raw setting for the grid also in the image sidebar (the grid mode) :)

kevininrussia
April 16th, 2021, 18:49
Now that I know where the RAW button is, it seems this extension does not use the RAW calculation in 4E. RAW works correctly with the extension not loaded.

https://i.imgur.com/4V0kNHz.png

GKEnialb
April 16th, 2021, 18:57
Yeah, technically the extension does not support 4E at all, other than what you've done with it. :) I'll take a look at it, though.

Kelrugem
April 16th, 2021, 19:06
For the raw distance, see Moon Wizard's post here: https://www.fantasygrounds.com/forums/showthread.php?67088-Getting-Distance-Multiplier-fomr-Image-Control&p=587168#post587168

Use the diagmult stuff; I believe that is has the value * star in case of raw :)

GKEnialb
April 16th, 2021, 20:00
Looks like it doesn't change the diagmult - set to 1 whether that flag is set or not, so I've posted a question in the Workshop on how to get that value. In the meantime, I've updated the extension to support 4E outside of raw, but will wait to upload it until I hear back on that.

bmos
April 16th, 2021, 20:19
It looks like there are two getDistanceDiagMult functions. imagecontrol.getDistanceDiagMult and Interface.getDistanceDiagMult.
So it might be as easy as removing the "Interface." in image.lua.

GKEnialb
April 16th, 2021, 21:13
Oooh. That does it. Thanks!

Version 2.1 uploaded which works with 4E and with the Raw Distance flag on maps (for 5E, this trumps the diagonal option, for other rulesets it acts the same as the Raw diagonal option of 5E).

Kelrugem
April 16th, 2021, 22:58
It looks like there are two getDistanceDiagMult functions. imagecontrol.getDistanceDiagMult and Interface.getDistanceDiagMult.
So it might be as easy as removing the "Interface." in image.lua.

Yeah, precisely, therefore I linked Moon Wizard's post where he shows the imagecontrol functions related to that :) The image sidebar is per image, so, no global settings :) (hence in the imagecontrol)

kevininrussia
April 17th, 2021, 02:47
What would be the best way to increase the font size?

GKEnialb
April 17th, 2021, 03:32
In token_height_indication.lua, after widget gets created ~line 156, you should be able to call widget.setFont(<font name>). I haven't played around with creating a font, so can't help you much beyond that. The Workshop forum (https://www.fantasygrounds.com/forums/forumdisplay.php?42-The-Workshop) is a great place to ask for advice.

kevininrussia
April 17th, 2021, 03:53
In token_height_indication.lua, after widget gets created ~line 156, you should be able to call widget.setFont(<font name>). I haven't played around with creating a font, so can't help you much beyond that. The Workshop forum (https://www.fantasygrounds.com/forums/forumdisplay.php?42-The-Workshop) is a great place to ask for advice.

Thanks! Super easy, barely an inconvenience :-)

https://i.imgur.com/BOOR53b.png

GKEnialb
April 17th, 2021, 16:46
@Kelrugem - yeah, should have followed the instructions explicitly. :) I was using Interface already, so thought the reference was just a shorthand.

@Kevininrussia - glad it was easy. If you want me to integrate the mods you made, send me what you have and I'll put it in (protected by options) so you don't have to merge in your changes each time I update (as long as the code isn't licensed).

Kelrugem
April 17th, 2021, 16:52
@Kelrugem - yeah, should have followed the instructions explicitly. :) I was using Interface already, so thought the reference was just a shorthand.

Hehe, no worries :D I should have explained it a bit more what I meant :D

kevininrussia
April 17th, 2021, 18:36
@Kelrugem - yeah, should have followed the instructions explicitly. :) I was using Interface already, so thought the reference was just a shorthand.

@Kevininrussia - glad it was easy. If you want me to integrate the mods you made, send me what you have and I'll put it in (protected by options) so you don't have to merge in your changes each time I update (as long as the code isn't licensed).

Awesome! Where should I send it?

GKEnialb
April 17th, 2021, 18:51
You can just put it in a reply to the PM I just sent. Thanks!

GKEnialb
April 17th, 2021, 23:50
Created version 3.0 with two new options, based upon kevininrussia mods:
- placement of the height text around the token (top, top right, right, bottom right, bottom, bottom left, left, top left)
- selection of medium or large font

MassSailor
April 19th, 2021, 06:21
Thanks for this extension, GKEnialb - started using it with my group and it's very handy!

Quick question - is there a way for players to be able to alter the height for NPC's that they own? My players have a familiar and pet spider in the party and they are able to modify their own character token's height but not the NPC's they own. Not a big deal adjusting on DM side, was just wondering if I was missing something to give them more control.

GKEnialb
April 20th, 2021, 02:14
Thanks, MassSailor. The players should be able to modify any tokens they own, but it's possible that "own" may mean something different for PCs vs NPCs. How did you give control of the NPCs to the players? Can the players move the NPC themselves (with the DM acceptance if token locked)?

MassSailor
April 20th, 2021, 06:32
I should have specified originally, but my question is for 5E using FG Unity. To give a player NPC control, I followed these steps:


Put the NPC on the combat tracker.
Change their faction to friendly
Drag the link from the Combat Tracker to the PC portrait on the desktop.
Put the NPC token on the map.


I also have Party Vision and Movement set to "On."

Results: Players are able to move NPCs and open up NPC character sheets to perform attacks, saves, etc. Players can change their own token height but not the height of the assigned NPC.

Just to be sure, I deleted NPCs that were active before enabling the extension and re-added them following the steps above after enabling - no change.

bmos
April 20th, 2021, 12:11
Thanks, MassSailor. The players should be able to modify any tokens they own, but it's possible that "own" may mean something different for PCs vs NPCs. How did you give control of the NPCs to the players? Can the players move the NPC themselves (with the DM acceptance if token locked)?Possibly you're checking for owner but the player is just a 'holder'?

GKEnialb
April 21st, 2021, 02:16
Possibly you're checking for owner but the player is just a 'holder'?

That is exactly what I'm doing. It looks like dragging the NPC to a player doesn't give ownership, which is why "party vision and movement" needs to be set to move as well. I'll see if I can allow changing the height when that flag is set.

mattekure
April 27th, 2021, 21:35
Players can never be "Owners" of NPC records. The record can be shared with a player so they may view it, but Ownership of NPC record types is restricted to the GM. The only record types that Players can have ownership over is Characters and Notes.

GKEnialb
April 28th, 2021, 14:51
Thanks, mattekure. That explains why I haven't been able to figure that out! :) And if someone who is not the owner tries to modify the DB element (where height is stored), bad things happen, so sorry, MassSailor, don't think I can provide that functionality.

bmos
April 28th, 2021, 15:26
Thanks, mattekure. That explains why I haven't been able to figure that out! :) And if someone who is not the owner tries to modify the DB element (where height is stored), bad things happen, so sorry, MassSailor, don't think I can provide that functionality.I think if someone who is holder tries to write to the DB they are allowed to, but it's more complicated to check if the user is a holder because there isn't an isHolder function.
You need to use getHolders() to get a table of users who are holders and then check if the user is in that table.

mattekure
April 28th, 2021, 16:01
If the client writes to the DB for something they dont own, it never really commits, it just appears so on the client end but isnt replicated to the GM. To replicate it properly, you would detect the desired change on the client, send an OOB Message that is picked up by the Host, then have the host make the change to the DB. In this way the change is always saved properly to the DB.

Svandal
April 28th, 2021, 19:53
I reported an error with distance calculations in this thread.
https://www.fantasygrounds.com/forums/showthread.php?66441-Combat-Modifier-Calculation-Extension/page4

It is this extension together with the combat modifer extension. When facing a large token the distance gets calculated incorrectly.
For explanation see other post. And since you might not know what the screenshot tells us. It adds a penalty to attack because of range between the tokens. Since they are on the same level and adjasent it should not be any more than 5 feet between them, but it is more since it gets a range penalty.

I do not know how to test this calculation with only this extension loaded so I do not know if this is a problem with your extension.

bmos
April 28th, 2021, 20:58
disregard

GKEnialb
April 29th, 2021, 01:56
If I remove the owner checks, the client (even when holding the token), gets errors on trying to create the node and set the value ("Database node not owned"). Nothing changes on the client side due to this...

GKEnialb
April 29th, 2021, 02:08
I reported an error with distance calculations in this thread.
https://www.fantasygrounds.com/forums/showthread.php?66441-Combat-Modifier-Calculation-Extension/page4

It is this extension together with the combat modifer extension. When facing a large token the distance gets calculated incorrectly.
For explanation see other post. And since you might not know what the screenshot tells us. It adds a penalty to attack because of range between the tokens. Since they are on the same level and adjasent it should not be any more than 5 feet between them, but it is more since it gets a range penalty.

I do not know how to test this calculation with only this extension loaded so I do not know if this is a problem with your extension.

Everything looks good from my side - the range displayed is the range provided if my calls are used. Perhaps dogfisc is expecting something different on the return and is getting skewed as a result. Here's what I get for different sizes (all 5' in the range arrow, which means it's returning 5' in the range function).

46181

I also tried with the massive creature size you had (changing the size to 80 in the combat tracker!) and it still returns 5'. Happy to talk to dogfsc about it.

kevininrussia
April 29th, 2021, 07:22
4E. Version 2.1

I'm getting this error quite frequently when moving a token.

[ERROR] Handler error: [string "campaign/scripts/image.lua"]:11: attempt to call global 'getGridSize' (a nil value)

This happens on both host and client. When the error happens we close the map window and re-open it. After that the error stops happening for the selected token so the players never have this issue after that. As GM I still do the first time I move a NPC. Then I close the window and reopen it then that NPC token will not throw the error.

I will try your latest version and see if it fixes the issue.

GKEnialb
April 30th, 2021, 02:56
Let me know if the latest version works. Do you have the grid turned on for the map? In 5E, at least, even if you don't, the grid settings are available, but not sure about 4E.

kevininrussia
April 30th, 2021, 03:12
Let me know if the latest version works. Do you have the grid turned on for the map? In 5E, at least, even if you don't, the grid settings are available, but not sure about 4E.

Yep, grid is on. I have messed around with the latest version with out errors but I usually see the errors when players on logged in so I will have to wait until next week for a proper test.

GKEnialb
April 30th, 2021, 03:21
Thanks - keep me informed. One thing to try (should only have to do this once, not every session) is to remove all the tokens from the map, add them back from the contact tracker, and reshare the map. I did that when I was first developing the extension and saw it behave better after that - not sure if it'll help in this case.

kevininrussia
April 30th, 2021, 03:57
Thanks for the tip! I did remove all the tokens from the map, but didn't stop and reshare the map.

MSW
April 30th, 2021, 09:28
Hi, you can open FG a second time and logg in as a player. So you don't need to wait for a "real" player.

bmos
April 30th, 2021, 16:37
Yep, grid is on. I have messed around with the latest version with out errors but I usually see the errors when players on logged in so I will have to wait until next week for a proper test.


Hi, you can open FG a second time and logg in as a player. So you don't need to wait for a "real" player.

Specifically, you can open a second copy of FG by right-clicking on it and clicking Fantasy Grounds Unity. Then you can click Join Game and type in localhost as the IP address.
The host session must be running as LAN (if I remember correctly).

BaneTBC
April 30th, 2021, 16:40
You can do it via cloud, just put your GM Name in the "Join by GM Name" box and hit start. I do it all the time without changing anything else from how I run my normal sessions.

kevininrussia
April 30th, 2021, 17:37
I have a laptop I use as the client for testing. I log into the host using local IP. Unfortunately I only see this issue when I have the group all logged in thus I said I would have to wait :)

Svandal
May 2nd, 2021, 20:54
Everything looks good from my side - the range displayed is the range provided if my calls are used. Perhaps dogfisc is expecting something different on the return and is getting skewed as a result. Here's what I get for different sizes (all 5' in the range arrow, which means it's returning 5' in the range function).

46181

I also tried with the massive creature size you had (changing the size to 80 in the combat tracker!) and it still returns 5'. Happy to talk to dogfsc about it.

Thank you for checking, yes I see that this extension gets the correct lenght when measuring (like your attached screenshot), I get the same results.

But as I already have reported the combat modifier gets another range when it tries to get a distance between two tokens:
https://www.fantasygrounds.com/forums/showthread.php?66441-Combat-Modifier-Calculation-Extension&p=596881&viewfull=1#post596881

And the same problem is in the Aura effects, see this thread for screenshot of the problem. Wrong range when it tries to get distance between two tokens.
https://www.fantasygrounds.com/forums/showthread.php?68035-Aura-Effects-for-Pathfinder-3-5E&p=597800&viewfull=1#post597800

Now I am only speculating by looking into the code in "aura", "combat modifier" and this extension. I did not really understand it since I only have started looking into the FG code yesterday, but let me speculate and somebody will probably correct me :)

I think both extensions gets their range between two tokens by calling: "Token.getDistanceBetween( ) function. Which I think your code modifies. So "aura" and "combat modifier" calls Token.getDistanceBetween(), and your code returns "nDistance.
This nDistance is not the same distance as you get when in your screenshot you see on the map. So maybe "aura" and "combat modifier" sends the wrong functions when it calls Token.getDistanceBetween()?

Here is what I think "aura" extension sends when calling Token.getDistanceBetween: (really short version, code does not look like this, but I "simplified" it)
ctEntries = CombatManager.getSortedCombatantList()
for _, node in pairs(ctEntries) do
Token.getDistanceBetween( CombatManager.getTokenFromCT(node) , "and the other token")

I hope this is some help for somebody, I would love to get this working :)

GKEnialb
May 2nd, 2021, 21:49
What you see on the screen is exactly what gets returned in getDistanceBetween - both get the result from calling the same function (distanceBetween). It looks like both of the other extensions are for 3.5/Pathfinder, so maybe something is up there? I do have different code for larger creatures for 5E than for other rulesets and all of that depends upon "standard" sizes. It looks like the size in your example is 35'. Is that correct? Does it work correctly if the size is 10, 15, 20, or 30 (those should map to large, huge, gargantuan, and colossal, respectively)? Either way, the distance should match what's on the screen, but that'd be a good place to start looking.

StarDrifter
May 3rd, 2021, 08:19
Hey, I really like the extension. But for some reason, in 5e, it changes the measurements of square markers to be the same as circles. So what should be a 20ft square says its a 10ft square instead.

Svandal
May 3rd, 2021, 20:44
This is with fantasy grounds unity latest live version. + Token height extension v3.0 and combat modifier extension.

First off I have a question which might help me find out what the problem is.
First off when measuring distance between tokens by selecting a target (where the arrow with a distance shows between tokens), where is your function distanceBetween called? Because it is not called from function getDistanceBetween?

Second question. It does not look like your extension uses the local function "getDistanceBetween" to anything? Have you just added that to your code to be compatible with other extensions?

Third: If that is the case it might be a cause of the problem. Because in the local function getDistanceBetween you are calling the "distanceBetween" function and sending them coordinates. What I am guessing now is that the coordinates you are sending the "distanceBetween" function is the coordinates for the tokens at the center. And since your function "distanceBetween" does not take into account the size of the tokens the lenght will be wrong.
I have not found out how to get the size of the tokens, that is probobly the trick. To send the x,y,z coordinates to the points that are closest to the two tokens instead of the center of it.

Fourth: I also think your math is wrong. As you see in the screenshot (bottom of screenshot where the range is shown) the distance between the two medium sized tokens are 20 measured to 20 feet. 10 feet in x direction, 10 feet in y direction 10 feet in z direction. I think you should be able to do this: From the token on the ground (the hero named "ffdsfsad"), the square that is 1 step in the x,y and z direction is directly towards the alchemical golem, that is one step. And now I only have one more step to go, 1 step in the x,y and z direction directly towards the golem. That is 2 steps. In pathfinder first step i 5 feet, second step i 10 feet. That is 15 feet total.

Can we just use this to calculate it, I think that should be correct: (I modified your code slightly in the function distanceBetween where have your "elseif diagMult == 0 then"

local hyp = math.sqrt((dx^2)+(dy^2)+(dz^2))
totalDistance = math.floor(hyp / gridsize)* units

SoxMax
May 4th, 2021, 01:17
I think I tracked down Svandal's problem with his very large dragon, he was using a non standard Pathfinder size of 35 ft. I've updated the non-5E sizeMultiplier calculation to be more generic.


local distancePerGrid = GameSystem.getDistanceUnitsPerGrid()
local nSpace = DB.getValue(ctNode, "space");
sizeMultiplier = ((nSpace / distancePerGrid ) - 1) * 0.5
if nSpace > distancePerGrid * 2 and nSpace % (distancePerGrid * 2) > 0 then
bExact = false
end

bmos
May 4th, 2021, 01:58
I think I tracked down Svandal's problem with his very large dragon, he was using a non standard Pathfinder size of 35 ft. I've updated the non-5E sizeMultiplier calculation to be more generic.ah! yes I had only gone as far as colossal since that is all we have in PFRPG.

SoxMax
May 4th, 2021, 03:38
Since I was in the the code too I was tinkering with the distance calculation since I tend to agree with Svandal about the current result being too long. I've been experimenting with this for the calculation of distance when the diagMult > 1



local diagMultIncrease = diagMult - 1
local distances = {dx, dy, dz}
table.sort(distances)
local first = distances[1] * diagMultIncrease / 2
local second = distances[2] * diagMultIncrease
local third = distances[3]
totalDistance = math.floor((first + second + third) / gridsize) * units


it seems to calculate a more "real" distance since halving both smaller legs tends to generate a much further distance than the real hypotenuse. The biggest thing I'm running up against though is what is the movement cost in 3.5/Pathfinder to go from 5,5,5 to 0,0,0?

GKEnialb
May 4th, 2021, 03:41
Version 3.1 upload to account for the arbitrary sizes and to fix StarDrifter's finding on the squares.

@SoxMax - thanks, I was thinking that may have been the issue. I think your code also works for 5E, so now I have a common determination. I appreciate that.

@Svandal - does that fix your primary concern? As for the other questions, just for information:


First off when measuring distance between tokens by selecting a target (where the arrow with a distance shows between tokens), where is your function distanceBetween called? Because it is not called from function getDistanceBetween?
It is called from getDistanceBetween, right before it returns the distance (line 30)


Second question. It does not look like your extension uses the local function "getDistanceBetween" to anything? Have you just added that to your code to be compatible with other extensions?
Correct, I override getDistanceBetween to allow other extensions to automatically get the height taken into account when used in conjunction with this extension (they don't need to do anything special unless they're overriding it as well, as it's a call from the core ruleset).


Third: ...
It was using "standard" sizes of tokens based upon their size, but with SoxMax's update, any size should work. So it was taking the size of the tokens into account (unfortunately with a lot of strange logic due to how FG handles creatures that are bigger than medium), just not all sizes...


Fourth: I also think your math is wrong.
My math is correct (at least it's does exactly what my intent is). In your sample picture, if they were at the same height, you'd get a range of 15'. Having one 10' higher than the other must add some amount to the distance. I used the same formula for adding a third dimension as is done with two dimensions (full effect from the longest axis, half from the shorter axes), which I believe meets the spirit of the rules. The formula you quoted is the actual raw distance - if that is more to your liking, you can make all the calculations raw by setting the Raw Distance flag on the map (see post #86, page 9).

Thanks for bringing up the issue - hopefully it works to your satisfaction now.

GKEnialb
May 4th, 2021, 03:59
it seems to calculate a more "real" distance since halving both smaller legs tends to generate a much further distance than the real hypotenuse.

I see your point, but that's also what happens in the 2D calculations as well - going diagonally 500 feet is 707 feet mathematically but 750 feet with the 3.5/PFRPG movement rules. They did that for simplicity, not for accuracy (and 5E goes even further). I'd prefer to follow that spirit and a quick search on people asking that question in a tabletop setting seems to agree with the formula I have. That being said, I'm easy - if there's enough of a request for a different method, I'd entertain it (at the risk of annoying people who like it as it is).

Svandal
May 4th, 2021, 06:28
I see your point, but that's also what happens in the 2D calculations as well - going diagonally 500 feet is 707 feet mathematically but 750 feet with the 3.5/PFRPG movement rules. They did that for simplicity, not for accuracy (and 5E goes even further). I'd prefer to follow that spirit and a quick search on people asking that question in a tabletop setting seems to agree with the formula I have. That being said, I'm easy - if there's enough of a request for a different method, I'd entertain it (at the risk of annoying people who like it as it is).

Of course, that makes sense. I got stuck last night with the idea that the real distance was the same as pathfinder distance diagonally, which is only correct for small distances. I understand it now, and since 99% of pathfinder rules are written for 2 dimensions we dont actually have good 3d measurement rules 😃.

And thank you for your other answers, I am new to lua, and new to the fantasy grounds code.

I will test this out later today, but it sounds like it is correct now. Thank you everybody.

Svandal
May 4th, 2021, 08:40
Well, I still think the problem is that the function getDistanceBetween does not take into account the token size at all. It only measures distances between token mid points.
The combat modifier extension calls the function getDistanceBetween when you make a ranged attack.
I added a Debug.chat in your code to see what distance gets returned. Look in the chat. As you can see it does not take into account token size when it returns the distance. And the distance returned is not the same as the measured distance with the "targeting function". The targeting function when measuring does something else than call the function getDistanceBetween to take into account token size.

See screenshot for details. The bug is there even with "standard" sized tokens.

bmos
May 4th, 2021, 12:00
It does look like token size is taken into account for pointers but not for getDistanceBetween. However, I think this might be consistent with how FG normally handles the getDistanceBetween function?
It's all a bit vague anyway since we don't know how tall creatures are.

mattekure
May 4th, 2021, 13:53
MoonWizard described how the getDistanceBetween() function works in this post. https://www.fantasygrounds.com/forums/showthread.php?65246-Experimental-APIs-for-FGU&p=576016&viewfull=1#post576016

So calculation is NOT done from center of token to center of token, but instead its done from center of grid square to center of grid square. whichever two grid squares within the token's space are closest.

For a visual representation of how it works, in this image the PC outlined in purple is targeting each of the NPCs. The distance calculation is done from the center of the purple square, to the center of each of the green squares. The green squares represent the closest grid square to the purple square.

https://imgur.com/2S1KwGW.jpg

SoxMax
May 4th, 2021, 13:54
I had a thought last night about sizes and why you need to do the fuzzy search. I was unfortunately right, it has to do with which square the targeting pointer is on with larger creatures. I've slightly updated my size multiplier code to account for this. Basically anything over 3 * GameSystem.getDistanceUnitsPerGrid() in size needs to be fuzzy matched.

local nSpace = DB.getValue(ctNode, "space");
local distancePerGrid = GameSystem.getDistanceUnitsPerGrid()
sizeMultiplier = ((nSpace / distancePerGrid) - 1) * 0.5
if nSpace > distancePerGrid * 3 then
bExact = false
end

mattekure
May 4th, 2021, 14:03
I had a thought last night about sizes and why you need to do the fuzzy search. I was unfortunately right, it has to do with which square the targeting pointer is on with larger creatures. I've slightly updated my size multiplier code to account for this. Basically anything over 3 * GameSystem.getDistanceUnitsPerGrid() in size needs to be fuzzy matched.

local nSpace = DB.getValue(ctNode, "space");
local distancePerGrid = GameSystem.getDistanceUnitsPerGrid()
sizeMultiplier = ((nSpace / distancePerGrid) - 1) * 0.5
if nSpace > distancePerGrid * 3 then
bExact = false
end

GameSystem.getDistanceUnitsPerGrid() will work for most maps, but FGU now has the ability to override that value per map. You would want to check for an override to that value in the image. The dB node would be "distancebaseunit"

bmos
May 4th, 2021, 15:17
GameSystem.getDistanceUnitsPerGrid() will work for most maps, but FGU now has the ability to override that value per map. You would want to check for an override to that value in the image. The dB node would be "distancebaseunit"I think this should do it. I have consolidated these calls to a single function so that it is easier to modify them in one place. It includes the bExact code posted by SoxMax as well, but not the proposed distance calculation change.


----------------------
-- CUSTOM ADDITIONS --
----------------------

local function getImageSettings()
local gridsize = getGridSize()
local units = DB.getValue(getDatabaseNode(), "distancebaseunit") or getDistanceBaseUnits()
local suffix = getDistanceSuffix()
local diagmult = getDistanceDiagMult() or Interface.getDistanceDiagMult()

-- Debug.chat(gridsize, units, suffix, diagmult)
return gridsize, units, suffix, diagmult
end

local function getDistanceBetween(sourceToken, targetToken)
if not sourceToken or not targetToken then
return
end

local gridsize, units, _, _ = getImageSettings()

local startz = 0
local endz = 0

local ctNodeOrigin = CombatManager.getCTFromToken(sourceToken)
if ctNodeOrigin then
startz = TokenHeight.getHeight(ctNodeOrigin) * gridsize / units

local ctNodeTarget = CombatManager.getCTFromToken(targetToken)
if ctNodeTarget then
endz = TokenHeight.getHeight(ctNodeTarget) * gridsize / units
end
end

local startx, starty = sourceToken.getPosition()
local endx, endy = targetToken.getPosition()

return distanceBetween(startx,starty,startz,endx,endy,end z)
end

function onInit()
if super and super.onInit() then
super.onInit()
end

Token.getDistanceBetween = getDistanceBetween
end

-- Distance between two locations in 3 dimensions.
local function distanceBetween(startx,starty,startz,endx,endy,end z,bSquare)
local gridsize, units, suffix, diagmult = getImageSettings()

local totalDistance = 0
local dx = math.abs(endx-startx)
local dy = math.abs(endy-starty)
local dz = math.abs(endz-startz)

if bSquare then
local hyp = math.sqrt((dx^2)+(dy^2)+(dz^2))
totalDistance = (hyp / gridsize)* units * 2
else
if diagmult == 1 then
-- Just a max of each dimension
local longestLeg = math.max(dx, dy, dz)
totalDistance = math.floor(longestLeg/gridsize+0.5)*units
elseif diagmult == 0 then
-- Get 3D distance directly
local hyp = math.sqrt((dx^2)+(dy^2)+(dz^2))
totalDistance = (hyp / gridsize)* units
else
-- You get full amount of the longest path and half from each of the others
local straight = math.max(dx, dy, dz)
local diagonal = 0
if straight == dx then
diagonal = math.floor((math.ceil(dy/gridsize) + math.ceil(dz/gridsize)) / 2) * gridsize
elseif straight == dy then
diagonal = math.floor((math.ceil(dx/gridsize) + math.ceil(dz/gridsize)) / 2) * gridsize
else
diagonal = math.floor((math.ceil(dx/gridsize) + math.ceil(dy/gridsize)) / 2) * gridsize
end
totalDistance = math.floor((straight + diagonal) / gridsize)
totalDistance = totalDistance * units
end
end

return totalDistance
end

function onMeasurePointer(pixellength,pointertype,startx,st arty,endx,endy)
local gridsize, units, suffix, diagmult = getImageSettings()
if not (gridsize and units and suffix and diagmult) then return; end
local bSquare = false
if pointertype == "rectangle" then
bSquare = true
end

local startz = 0
local endz = 0

local ctNodeOrigin = getCTNodeAt(startx,starty,gridsize)
if ctNodeOrigin then
local ctNodeTarget = getCTNodeAt(endx,endy,gridsize)

if ctNodeTarget then
startz = TokenHeight.getHeight(ctNodeOrigin) * gridsize / units
endz = TokenHeight.getHeight(ctNodeTarget) * gridsize / units
end
end

local distance = distanceBetween(startx,starty,startz,endx,endy,end z,bSquare)
if distance == 0 then
return ""
else
local stringDistance = nil
if diagmult == 0 then
stringDistance = string.format("%.1f", distance)
else
stringDistance = string.format("%.0f", distance)
end
return stringDistance .. suffix
end
end

function getCTNodeAt(basex, basey, gridsize)
local allTokens = getTokens()
for _, oneToken in pairs(allTokens) do
local x,y = oneToken.getPosition()
local ctNode = CombatManager.getCTFromToken(oneToken)
local bExact = true
local sizeMultiplier = 0

-- bmos / SoxMax supporting other rulesets
local nSpace = DB.getValue(ctNode, "space");
local distancePerGrid = GameSystem.getDistanceUnitsPerGrid()
sizeMultiplier = ((nSpace / distancePerGrid) - 1) * 0.5
if nSpace > distancePerGrid * 3 then
bExact = false
end

local bFound = false
if bExact then
bFound = exactMatch(basex, basey, x, y, sizeMultiplier, gridsize)
else
bFound = matchWithinSize(basex, basey, x, y, sizeMultiplier, gridsize)
end

if bFound then
return ctNode
end
end
end

function exactMatch(startx, starty, endx, endy, sizeMultiplier, gridsize)
local equal = false

local modx = endx
local mody = endy
if modx > startx then
modx = modx - gridsize * sizeMultiplier
elseif modx < startx then
modx = modx + gridsize * sizeMultiplier
end
if mody > starty then
mody = mody - gridsize * sizeMultiplier
elseif mody < starty then
mody = mody + gridsize * sizeMultiplier
end
if modx == startx and mody == starty then
equal = true
end

return equal
end

function matchWithinSize(startx, starty, endx, endy, sizeMultiplier, gridsize)
local equal = false

local modx = endx
local mody = endy
local lowerBoundx = endx
local lowerBoundy = endy
local upperBoundx = endx
local upperBoundy = endy

if endx > startx then
lowerBoundx = endx - gridsize * sizeMultiplier
elseif endx < startx then
upperBoundx = endx + gridsize * sizeMultiplier
end
if endy > starty then
lowerBoundy = endy - gridsize * sizeMultiplier
elseif endy < starty then
upperBoundy = upperBoundy + gridsize * sizeMultiplier
end

if startx >= lowerBoundx and startx <= upperBoundx and starty >= lowerBoundy and starty <= upperBoundy then
equal = true
end

return equal
end

the image settings could alternately be called onInit and then set script-wide variables so that they don't have to be re-checked over and over (although then it would not pick up changes live so I think the solution I have set up here is best).

bmos
May 4th, 2021, 15:42
For some reason, making the map full screen/"sending to background" seems to make the distance calculation revert to original smiteworks version.
Is anyone else noticing this? I don't recall seeing it discussed here.

EDIT: It looks like there are other windowclass names for images sent to background or full screen. Probably the extension.xml file needs to have a change made so that image.lua is used in all these places.
EDIT3: You can use this in extension.xml instead of the current windowclass merge you're using to replace image.lua:

<template name="image_record_step">
<imagecontrol name="image" merge="join">
<script file="campaign/scripts/image.lua" />
</imagecontrol>
</template>

GKEnialb
May 4th, 2021, 18:27
Wow, great discussion and super helpful updates. I've folded it all into the extension (made a minor mod to use bmos's updates in the SoxMax code with mattekure's suggestion) and released v3.2. Tried it with the various sizes and seems to work fine, but the off-nominal cases is where all the bugs are lurking. Svandal is the expert at finding those! :) Hopefully now it'll work. (oh, I should have paid more attention to your screenshot - I'll check to see why onMeasurePointer and getDistanceBetween are giving different results. Presumably they're getting different starting locations for the same tokens).

bmos
May 4th, 2021, 18:49
All I'm still looking at currently is how to get the suffix from GameSystem.xml.
It would allow getting rid of the 4E suffix override (and further improve support for more rulesets).

GKEnialb
May 4th, 2021, 18:55
Awesome. I spent a while looking into it and went the hardcoding route once my brain started hurting too much...

Kelrugem
May 4th, 2021, 19:00
All I'm still looking at currently is how to get the suffix from GameSystem.xml.
It would allow getting rid of the 4E suffix override (and further improve support for more rulesets).

For the suffix stuff etc., I'd rather use the sidebar of an image (grid mode), where one can overwrite the typical increment and the suffix of range indicators :) Then one can even adjust that kind of stuff ingame :) (I have some prototype for that in my height extension, not uploaded yet; I can try to find that prototype if you want to add such things :) )

bmos
May 4th, 2021, 19:06
For the suffix stuff etc., I'd rather use the sidebar of an image (grid mode), where one can overwrite the typical increment and the suffix of range indicators :) Then one can even adjust that kind of stuff ingame :) (I have some prototype for that in my height extension, not uploaded yet; I can try to find that prototype if you want to add such things :) )Certainly. That is the primary source using getDistanceSuffix(), but I like to configure each of those variables to fallback to the gamesystem file values if it doesn't get them from the image sidebar.
I did this with "local diagmult = getDistanceDiagMult() or Interface.getDistanceDiagMult()"

Kelrugem
May 4th, 2021, 19:07
Certainly. That is the primary source using getDistanceSuffix(), but I like to configure each of those variables to fallback to the gamesystem file values if it doesn't get them from the image sidebar.

ah, I see :D

SoxMax
May 4th, 2021, 22:17
To account for the problem in getDistanceBetween I tried experimenting with a new way of generating the distances which is more reliant on the built in methods. This generates a pretty good result, but gets wonky when height is the primary distance between targets. It does have the advantage however of also overwriting the imagecontrol getDistanceBetween making it consistent with the Token.getDistanceBetween function.



----------------------
-- CUSTOM ADDITIONS --
----------------------

local function exactMatch(startx, starty, endx, endy, sizeMultiplier, gridsize)
local equal = false
local modx = endx
local mody = endy
-- Debug.console(modx, startx, mody, starty)
if modx > startx then
modx = modx - gridsize * sizeMultiplier
elseif modx < startx then
modx = modx + gridsize * sizeMultiplier
end
if mody > starty then
mody = mody - gridsize * sizeMultiplier
elseif mody < starty then
mody = mody + gridsize * sizeMultiplier
end
-- Debug.console(modx, startx, mody, starty)
if modx == startx and mody == starty then
equal = true
end

return equal
end

local function matchWithinSize(startx, starty, endx, endy, sizeMultiplier, gridsize)
local equal = false

local lowerBoundx = endx
local lowerBoundy = endy
local upperBoundx = endx
local upperBoundy = endy

if endx > startx then
lowerBoundx = endx - gridsize * sizeMultiplier
elseif endx < startx then
upperBoundx = endx + gridsize * sizeMultiplier
end
if endy > starty then
lowerBoundy = endy - gridsize * sizeMultiplier
elseif endy < starty then
upperBoundy = upperBoundy + gridsize * sizeMultiplier
end
-- Debug.console(lowerBoundx, startx, upperBoundx, lowerBoundy, starty, upperBoundy)
if startx >= lowerBoundx and startx <= upperBoundx and starty >= lowerBoundy and starty <= upperBoundy then
equal = true
end

return equal
end

local function getCTNodeAt(basex, basey)

-- Debug.console("start getCTNodeAt")
local allTokens = getTokens()
for _, oneToken in pairs(allTokens) do
local x,y = oneToken.getPosition()
local ctNode = CombatManager.getCTFromToken(oneToken)
local bExact = true

local nSpace = DB.getValue(ctNode, "space");
local distancePerGrid = GameSystem.getDistanceUnitsPerGrid()
local sizeMultiplier = ((nSpace / distancePerGrid) - 1) * 0.5
if nSpace > distancePerGrid * 3 then
bExact = false
end

local gridsize = getGridSize()
local bFound = false
if bExact then
bFound = exactMatch(basex, basey, x, y, sizeMultiplier, gridsize)
else
bFound = matchWithinSize(basex, basey, x, y, sizeMultiplier, gridsize)
end

-- if sizeMultiplier > 0 then
-- local exactMatch = exactMatch(basex, basey, x, y, sizeMultiplier, gridsize)
-- local matchWithinSize = matchWithinSize(basex, basey, x, y, sizeMultiplier, gridsize)
-- Debug.console(ctNode, "sizeMultiplier", sizeMultiplier, "gridsize", gridsize)
-- Debug.console("exactMatch", exactMatch, "matchWithinSize", matchWithinSize)
-- end

if bFound then
return ctNode
end
end
end

local function calculate3dDistance(flatDistance, heightDistance)
local distancePerGrid = GameSystem.getDistanceUnitsPerGrid()
local diagMult = getDistanceDiagMult()
local totalDistance = flatDistance
if diagMult == 0 then
totalDistance = math.sqrt((flatDistance ^ 2) + (heightDistance ^ 2))
elseif diagMult == 1 then
totalDistance = math.max(flatDistance, heightDistance)
else
if flatDistance > heightDistance then
totalDistance = flatDistance + heightDistance * (diagMult - 1)
else
totalDistance = heightDistance + flatDistance * (diagMult - 1)
end
totalDistance = math.ceil(totalDistance / distancePerGrid) * distancePerGrid
end
Debug.chat(totalDistance)
return totalDistance
end

local getDistanceBetweenTokens_orig
local function getDistanceBetweenTokens(sourceToken, targetToken)
local flatDistance = getDistanceBetweenTokens_orig(sourceToken, targetToken)
if not flatDistance then
return nil
end

local sourceHeight = 0
local targetHeight = 0
local ctNodeOrigin = CombatManager.getCTFromToken(sourceToken)
if ctNodeOrigin then
sourceHeight = TokenHeight.getHeight(ctNodeOrigin)
local ctNodeTarget = CombatManager.getCTFromToken(targetToken)
if ctNodeTarget then
targetHeight = TokenHeight.getHeight(ctNodeTarget)
end
end
local heightDistance = math.abs(sourceHeight - targetHeight)
return calculate3dDistance(flatDistance, heightDistance)
end

function getDistanceBetween(source, target)
-- Debug.console("getDistanceBetween")
-- Debug.console("types", type(source), type(target))
if type(source) == "tokeninstance" and type(target) == "tokeninstance" then
return getDistanceBetweenTokens(source, target)
end
local flatDistance = super.getDistanceBetween(source, target)
if not flatDistance then
return nil
end

local sourceHeight = 0
local targetHeight = 0
local ctNodeOrigin = getCTNodeAt(source.x, source.y)
if ctNodeOrigin then
sourceHeight = TokenHeight.getHeight(ctNodeOrigin)
local ctNodeTarget = getCTNodeAt(target.x, target.y)
if ctNodeTarget then
targetHeight = TokenHeight.getHeight(ctNodeTarget)
end
end
local heightDistance = math.abs(sourceHeight - targetHeight)
return calculate3dDistance(flatDistance, heightDistance)
end

function onMeasurePointer(pixellength,pointertype,startx,st arty,endx,endy)
local distance = getDistanceBetween({x = startx, y = starty}, {x = endx, y = endy})
if distance == 0 then
return ""
else
local stringDistance = nil
if diagMult == 0 then
stringDistance = string.format("%.1f", distance)
else
stringDistance = string.format("%.0f", distance)
end
return stringDistance .. getDistanceSuffix()
end
end

function onInit()
if super and super.onInit() then
super.onInit()
end
getDistanceBetweenTokens_orig = Token.getDistanceBetween
Token.getDistanceBetween = getDistanceBetweenTokens
end

bmos
May 4th, 2021, 22:34
To account for the problem in getDistanceBetween I tried experimenting with a new way of generating the distances which is more reliant on the built in methods. This generates a pretty good result, but gets wonky when height is the primary distance between targets. It does have the advantage however of also overwriting the imagecontrol getDistanceBetween making it consistent with the Token.getDistanceBetween function.



----------------------
-- CUSTOM ADDITIONS --
----------------------

local function exactMatch(startx, starty, endx, endy, sizeMultiplier, gridsize)
local equal = false
local modx = endx
local mody = endy
-- Debug.console(modx, startx, mody, starty)
if modx > startx then
modx = modx - gridsize * sizeMultiplier
elseif modx < startx then
modx = modx + gridsize * sizeMultiplier
end
if mody > starty then
mody = mody - gridsize * sizeMultiplier
elseif mody < starty then
mody = mody + gridsize * sizeMultiplier
end
-- Debug.console(modx, startx, mody, starty)
if modx == startx and mody == starty then
equal = true
end

return equal
end

local function matchWithinSize(startx, starty, endx, endy, sizeMultiplier, gridsize)
local equal = false

local lowerBoundx = endx
local lowerBoundy = endy
local upperBoundx = endx
local upperBoundy = endy

if endx > startx then
lowerBoundx = endx - gridsize * sizeMultiplier
elseif endx < startx then
upperBoundx = endx + gridsize * sizeMultiplier
end
if endy > starty then
lowerBoundy = endy - gridsize * sizeMultiplier
elseif endy < starty then
upperBoundy = upperBoundy + gridsize * sizeMultiplier
end
-- Debug.console(lowerBoundx, startx, upperBoundx, lowerBoundy, starty, upperBoundy)
if startx >= lowerBoundx and startx <= upperBoundx and starty >= lowerBoundy and starty <= upperBoundy then
equal = true
end

return equal
end

local function getCTNodeAt(basex, basey)

-- Debug.console("start getCTNodeAt")
local allTokens = getTokens()
for _, oneToken in pairs(allTokens) do
local x,y = oneToken.getPosition()
local ctNode = CombatManager.getCTFromToken(oneToken)
local bExact = true

local nSpace = DB.getValue(ctNode, "space");
local distancePerGrid = GameSystem.getDistanceUnitsPerGrid()
local sizeMultiplier = ((nSpace / distancePerGrid) - 1) * 0.5
if nSpace > distancePerGrid * 3 then
bExact = false
end

local gridsize = getGridSize()
local bFound = false
if bExact then
bFound = exactMatch(basex, basey, x, y, sizeMultiplier, gridsize)
else
bFound = matchWithinSize(basex, basey, x, y, sizeMultiplier, gridsize)
end

-- if sizeMultiplier > 0 then
-- local exactMatch = exactMatch(basex, basey, x, y, sizeMultiplier, gridsize)
-- local matchWithinSize = matchWithinSize(basex, basey, x, y, sizeMultiplier, gridsize)
-- Debug.console(ctNode, "sizeMultiplier", sizeMultiplier, "gridsize", gridsize)
-- Debug.console("exactMatch", exactMatch, "matchWithinSize", matchWithinSize)
-- end

if bFound then
return ctNode
end
end
end

local function calculate3dDistance(flatDistance, heightDistance)
local distancePerGrid = GameSystem.getDistanceUnitsPerGrid()
local diagMult = getDistanceDiagMult()
local totalDistance = flatDistance
if diagMult == 0 then
totalDistance = math.sqrt((flatDistance ^ 2) + (heightDistance ^ 2))
elseif diagMult == 1 then
totalDistance = math.max(flatDistance, heightDistance)
else
if flatDistance > heightDistance then
totalDistance = flatDistance + heightDistance * (diagMult - 1)
else
totalDistance = heightDistance + flatDistance * (diagMult - 1)
end
totalDistance = math.ceil(totalDistance / distancePerGrid) * distancePerGrid
end
Debug.chat(totalDistance)
return totalDistance
end

local getDistanceBetweenTokens_orig
local function getDistanceBetweenTokens(sourceToken, targetToken)
local flatDistance = getDistanceBetweenTokens_orig(sourceToken, targetToken)
if not flatDistance then
return nil
end

local sourceHeight = 0
local targetHeight = 0
local ctNodeOrigin = CombatManager.getCTFromToken(sourceToken)
if ctNodeOrigin then
sourceHeight = TokenHeight.getHeight(ctNodeOrigin)
local ctNodeTarget = CombatManager.getCTFromToken(targetToken)
if ctNodeTarget then
targetHeight = TokenHeight.getHeight(ctNodeTarget)
end
end
local heightDistance = math.abs(sourceHeight - targetHeight)
return calculate3dDistance(flatDistance, heightDistance)
end

function getDistanceBetween(source, target)
-- Debug.console("getDistanceBetween")
-- Debug.console("types", type(source), type(target))
if type(source) == "tokeninstance" and type(target) == "tokeninstance" then
return getDistanceBetweenTokens(source, target)
end
local flatDistance = super.getDistanceBetween(source, target)
if not flatDistance then
return nil
end

local sourceHeight = 0
local targetHeight = 0
local ctNodeOrigin = getCTNodeAt(source.x, source.y)
if ctNodeOrigin then
sourceHeight = TokenHeight.getHeight(ctNodeOrigin)
local ctNodeTarget = getCTNodeAt(target.x, target.y)
if ctNodeTarget then
targetHeight = TokenHeight.getHeight(ctNodeTarget)
end
end
local heightDistance = math.abs(sourceHeight - targetHeight)
return calculate3dDistance(flatDistance, heightDistance)
end

function onMeasurePointer(pixellength,pointertype,startx,st arty,endx,endy)
local distance = getDistanceBetween({x = startx, y = starty}, {x = endx, y = endy})
if distance == 0 then
return ""
else
local stringDistance = nil
if diagMult == 0 then
stringDistance = string.format("%.1f", distance)
else
stringDistance = string.format("%.0f", distance)
end
return stringDistance .. getDistanceSuffix()
end
end

function onInit()
if super and super.onInit() then
super.onInit()
end
getDistanceBetweenTokens_orig = Token.getDistanceBetween
Token.getDistanceBetween = getDistanceBetweenTokens
end

I suggested that same approach around v1.9 (that's why getDistanceBetweenTokens_orig was there) but GKEnialb wanted to do it all in a single function rather than calling the original function.
I actually think that was the right call since otherwise different formulas are being used (which is causing the weirdness you mention when height is the primary differentiator). Supposedly the original function being called there is similar to this (https://www.fantasygrounds.com/forums/showthread.php?41500-Modifying-distance-calculation&p=368188&viewfull=1#post368188).

GKEnialb
May 5th, 2021, 00:40
Yeah, I appreciate the thought Soxmax, but I don't think it'll work with horizontal being calculated separately from vertical. There are some other interesting things in what you posted, though, so I'll play with something in between.

GKEnialb
May 5th, 2021, 02:57
Sorry, Svandal, I do see that getDistanceBetween doesn't work right for tokens larger than one square - you were absolutely right that it's just using the center and that it doesn't match the arrow. I had figured that since both onMeasurePointer and getDistanceBetween were both calling distanceBetween, they must be getting the same result, but didn't think about the fact that getDistanceBetween starts with tokens instead of coordinates (and getting the position of those tokens returns the center). The good news is that I know how to fix it - just have to find the square in the large target closest to the other (as mattekure points out in post 135). I'll have a fix shortly.


* Well, "shortly" may not be too accurate. I implemented finding the closest square, but apparently that's not exactly how it works. I think it takes the line between the center of each token and finds the furthest square of each token along that line. Looking at this image:

46366

The closest square is in red and is 20' away (with the variant/3.5/PFRPG counting). However, the old getDistanceBetween (and the logic I use in the arrow) both come up with 25', which would be true if the square directly south of the red square was chosen. Not sure that I like that, but better to make it match what the core comes up with...

kevininrussia
May 5th, 2021, 06:09
4E
Token Height 3.2
Aura-Effects .10

New Campaign, no other extensions.

I get this error on token move.

https://i.imgur.com/ABGKEFO.png

Removing Token Height removes the error.

bmos
May 5th, 2021, 11:53
4E
Token Height 3.2
Aura-Effects .10

New Campaign, no other extensions.

I get this error on token move.

https://i.imgur.com/ABGKEFO.png

Removing Token Height removes the error.Oops, it looks like I made a mistake in my suggested code.
The distancebetween function should be above the getDistanceBetween function.

SoxMax
May 5th, 2021, 14:18
The closest square is in red and is 20' away (with the variant/3.5/PFRPG counting). However, the old getDistanceBetween (and the logic I use in the arrow) both come up with 25', which would be true if the square directly south of the red square was chosen. Not sure that I like that, but better to make it match what the core comes up with...

If its possible I think it would be better to fix bug with the current getDistanceBetween, however as that probably requires changing how the targeting arrows are drawn that might be quite the effort.

kevininrussia
May 5th, 2021, 17:24
Oops, it looks like I made a mistake in my suggested code.
The distancebetween function should be above the getDistanceBetween function.

Yep, that fixed it. Thanks!

GKEnialb
May 6th, 2021, 02:22
If its possible I think it would be better to fix bug with the current getDistanceBetween, however as that probably requires changing how the targeting arrows are drawn that might be quite the effort.

Yeah, that would be a lot more involved and I'm afraid may have other repercussions down the line. I can replicate the existing behavior with some math, so I'll go that way...

GKEnialb
May 6th, 2021, 02:37
Oops, it looks like I made a mistake in my suggested code.
The distancebetween function should be above the getDistanceBetween function.

Thanks - I noticed that last night and thought I had broken something when trying to update the distance equations...

GKEnialb
May 6th, 2021, 06:24
Okay, posted v3.3 which (hopefully) fixes getDistanceBetween to find the correct square to perform the distance between...

Svandal
May 6th, 2021, 19:58
v3.3 Fixed getDistanceBetween - thanks to Svandal for being persistent on pointing out the issue

I feel so honored. My first mentino in an update. Svandal, the man who never stopped nagging :)

I have tested it, and it seems to be working, so great job. It will speed up our games much when there is 3D combat.

GKEnialb
May 7th, 2021, 00:53
But it was necessary nagging to get me past the mental block that the arrow and function had to return the same value... :) Glad it's working for you now.

rhagelstrom
May 7th, 2021, 03:30
46423

I got this error in my campaign tonight. Everything was working fine and then the last battle I got this error. Never changed maps.

GKEnialb
May 7th, 2021, 03:43
46423

I got this error in my campaign tonight. Everything was working fine and then the last battle I got this error. Never changed maps.

Very odd. Did you add any tokens to the map between the time it was working and when you got the error? Do you have any other extensions loaded? If it does come up again, you may be able to kick it by removing/re-adding the tokens from the combat tracker and resharing the map. That's just a system call, so not really sure how it could have disappeared.

rhagelstrom
May 7th, 2021, 03:49
Very odd. Did you add any tokens to the map between the time it was working and when you got the error? Do you have any other extensions loaded? If it does come up again, you may be able to kick it by removing/re-adding the tokens from the combat tracker and resharing the map. That's just a system call, so not really sure how it could have disappeared.

Yes I added an encounter to the map however I also added encounters previous to this and I didn't get the error. Yes there are other extensions so I get that probably isn't much help. I was rather confused why this was throwing an error as well.

bmos
May 7th, 2021, 13:30
46423

I got this error in my campaign tonight. Everything was working fine and then the last battle I got this error. Never changed maps.


Very odd. Did you add any tokens to the map between the time it was working and when you got the error? Do you have any other extensions loaded? If it does come up again, you may be able to kick it by removing/re-adding the tokens from the combat tracker and resharing the map. That's just a system call, so not really sure how it could have disappeared.

notice the error is coming from line 7 which in your extension doesn't call getGridSide.
almost certainly an extension conflict.

GKEnialb
May 7th, 2021, 15:52
notice the error is coming from line 7 which in your extension doesn't call getGridSide.
almost certainly an extension conflict.

Actually in the latest, line 7 is (part of the getImageSettings() function):

local gridsize = getGridSize()

The question I'm struggling with is whether it's better to protect against these strange cases (if getGridSize then ...) and just have the extension silently stop working, return some default value that may generally work but not always (like squirelling away the values when the image is initialized), or let the error occur and have it complain when it stops working... I can't think of any way to prevent a function from somehow disappearing (or why it would, unless there is an odd extension conflict).

@rhagelstrom - was there anything different about the last encounter that you added than the earlier encounters? Were the tokens prearranged in the encounter or did you add the NPCs to the combat tracker and then drag from there to the map? Was the error on the DM console, the players' consoles, or both?

rhagelstrom
May 7th, 2021, 18:49
I loaded up the campaign again today and ran the same encounter without issue. I was running a map that was created with assets within fantasy grounds so there is that wild card as well. For now I'd say its not reproducible.

The issue was on the DM side. The larger issue with the error is that when the error was thrown it wouldn't allow me to make ranged attacks so I had to just do them manually. I agree with @GKEnialb that it really shouldn't happen.

bmos
May 7th, 2021, 19:24
Yes there are other extensions so I get that probably isn't much help.Perhaps you could get a list together of what extensions you're using?

EDIT: kevininrussia has been having this issue too:
https://www.fantasygrounds.com/forums/showthread.php?68090-Handler-error

GKEnialb
May 7th, 2021, 21:06
Perhaps you could get a list together of what extensions you're using?

EDIT: kevininrussia has been having this issue too:
https://www.fantasygrounds.com/forums/showthread.php?68090-Handler-error

It would be great to see the list of extensions (and ruleset) for both rhagelstrom and kevininrussia. In the meantime, I've uploaded v3.4 which will keep things running if the functions get dropped so you won't have to switch to doing things manually in the middle of a battle...

kevininrussia
May 7th, 2021, 21:39
It would be great to see the list of extensions (and ruleset) for both rhagelstrom and kevininrussia. In the meantime, I've uploaded v3.4 which will keep things running if the functions get dropped so you won't have to switch to doing things manually in the middle of a battle...

I have not experienced this issue after I updated Token Height Indicator extension a week ago. I will report back if it pops its head up again.

GKEnialb
May 7th, 2021, 21:43
Great - thanks.

bmos
May 7th, 2021, 22:39
In the meantime, I've uploaded v3.4 which will keep things running if the functions get dropped so you won't have to switch to doing things manually in the middle of a battle...clever workaround!

rhagelstrom
May 8th, 2021, 02:11
I tried to recreate multiple times but was unable. I don't feel like list of extensions will help but here it is:
Advanced Effects
Attunement Tracker
Automatic Critical Damage
Automatic Death Resistance
Automatic Flanking and Range (no issue year+)
Automatic Halfling Luck
Automatic Mirror Image
Automatic Save Advantage
Automatic Sneak Attack
Better Combat Effects (Self ext for homebrew)
Constutional Amendments
Dark Luck (self ext for homebrew)
Indicators
Miss Flavor Text
Turn Based Effects
Aura Effects
Drowbe's Chat
MN Combat Stats
Random Encounter Gen
Token Height

GKEnialb
May 8th, 2021, 03:42
Thanks - it helps to see if any of them override any of the same things that this extension does (or one of the functions that disappear for no apparent reason). Hopefully you won't see it again (or the workaround from 3.4 adequately hides it from you).

EllivasKram
May 8th, 2021, 07:44
Anyone having major issues with this extn in the TEST version of FGU.

Throws up errors every few seconds

bmos
May 8th, 2021, 11:33
Anyone having major issues with this extn in the TEST version of FGU.

Throws up errors every few seconds

Are you using the new version 3.4?

GKEnialb
May 8th, 2021, 17:25
Also, can you post a screenshot or log snippet of the errors, list which ruleset you're using, and any other extensions? I'll take a look at the test channel, but unfortunately can make no promises - I can't make any modifications to make things work in the test channel that would impact the stable channel.

eporrini
May 8th, 2021, 21:50
This extension is now broken for me as well. I have a session coming up tonight so I had to disable it for now. It threw errors when opening the map or even scrolling across characters on the combat tracker. I will try and get something posted with some logs.

GKEnialb
May 8th, 2021, 22:04
This extension is now broken for me as well. I have a session coming up tonight so I had to disable it for now. It threw errors when opening the map or even scrolling across characters on the combat tracker. I will try and get something posted with some logs.

Are you on the Live channel or the Test channel? And are you using v3.4?

eporrini
May 8th, 2021, 23:44
Are you on the Live channel or the Test channel? And are you using v3.4?

I’m using FGU latest release code and 3.4 of this extension. Not anything with test. I use a lot of extensions, which all worked prior to loading the latest version. Will upload some logs as soon as I can.

GKEnialb
May 8th, 2021, 23:54
I’m using FGU latest release code and 3.4 of this extension. Not anything with test. I use a lot of extensions, which all worked prior to loading the latest version. Will upload some logs as soon as I can.

Thanks- appreciate it.

GKEnialb
May 9th, 2021, 20:28
Uploaded v3.5 - fixed error spamming for nSpace when there were tokens on the map that weren't in the combat tracker. Hopefully that's what was being reported.

eporrini
May 10th, 2021, 22:47
Uploaded v3.5 - fixed error spamming for nSpace when there were tokens on the map that weren't in the combat tracker. Hopefully that's what was being reported.

I tested out v3.5 today and it's working again. Many thanks for the rapid response!!!

mattekure
May 11th, 2021, 00:26
Uploaded v3.5 - fixed error spamming for nSpace when there were tokens on the map that weren't in the combat tracker. Hopefully that's what was being reported.

I saw 3.5 mentioned on the first post, but when I download the attached ext it shows as 3.4.

GKEnialb
May 11th, 2021, 01:20
I saw 3.5 mentioned on the first post, but when I download the attached ext it shows as 3.4.

Sorry about that - it really was 3.5 but I missed updating the text in the extension file. It's all good now.

kevininrussia
May 12th, 2021, 19:13
3.5 is causing the latest version of Aura Effects not to add effects correctly. I reported on the Aura Effects thread also.

https://www.fantasygrounds.com/forums/showthread.php?57417-5E-Aura-Effects&p=599638&viewfull=1#post599638

bmos
May 12th, 2021, 19:40
3.5 is causing the latest version of Aura Effects not to add effects correctly. I reported on the Aura Effects thread also.

https://www.fantasygrounds.com/forums/showthread.php?57417-5E-Aura-Effects&p=599638&viewfull=1#post599638It looks like the issue is regarding diagonals
I think it's a discrepancy between the result of getDistanceBetween in this extension vs normal FG.

EllivasKram
May 12th, 2021, 22:37
With V3.5 EXTN - Any GM/DM (Using 5E FGU) attack using Combat Tracker NPC 'Attacks' and then dropping attack DIE onto PC from NPC CT causing an issue today with 'Token Height Indication' Extension.

[5/12/2021 10:02:02 PM] [ERROR] Script execution error: [string "image"]:10: attempt to call field 'onDrop' (a nil value)

Even dropping the 'Targeting Icon' from the CT is causing this issue.

Not seeing previous issues now - Which is good.

GKEnialb
May 13th, 2021, 02:25
It looks like the issue is regarding diagonals
I think it's a discrepancy between the result of getDistanceBetween in this extension vs normal FG.

Oops - I protected against a division by 0 when a token was directly above or below another but then promptly divided by 0 later in the same function. Fixed in v3.6 - tested with your Aura Effects and it works fine now.


With V3.5 EXTN - Any GM/DM (Using 5E FGU) attack using Combat Tracker NPC 'Attacks' and then dropping attack DIE onto PC from NPC CT causing an issue today with 'Token Height Indication' Extension.

[5/12/2021 10:02:02 PM] [ERROR] Script execution error: [string "image"]:10: attempt to call field 'onDrop' (a nil value)

Even dropping the 'Targeting Icon' from the CT is causing this issue.

I can't recreate this and I don't call onDrop myself, but I imagine it's related to the original image disappearing sometimes (and unfortunately, can't override every function in image.lua). I'll see if anybody on the workshop has thoughts on how that could happen. If you can recreate and let me know the steps to do it, that'd help (including if it worked for a bit and then stopped working during the session).

Jaegar
May 13th, 2021, 20:06
Thank toy! this is awesome

rhagelstrom
May 13th, 2021, 20:09
With the new FGU version 4.1

With token height enabled, unable to drag the faction from the combat tracker to populate the map. I can drag individual PC/NPC from the CT to populate map, but the group faction drag no longer works.

Weissrolf
May 14th, 2021, 00:20
Thanks for the extension! I patched the XML file to include Pathfinder 2 and it seems to work properly.

Diagonal target range calculation confuses me, though. Why is this 10 ft instead of 5 ft?

https://i.imgur.com/v0K3G6C.png

bmos
May 14th, 2021, 01:19
Thanks for the extension! I patched the XML file to include Pathfinder 2 and it seems to work properly.

Diagonal target range calculation confuses me, though. Why is this 10 ft instead of 5 ft?

https://i.imgur.com/v0K3G6C.pngit isn't like that in 5e/pfrpg/etc. so perhaps not working properly in pfrpg2
EDIT: I think I was wrong and didn't notice the second creature is 5 ft up in the air.

Weissrolf
May 14th, 2021, 01:28
Ah, yes. I just checked. Thanks for testing this. Too bad for us PF2 groups, but still useful.

Diablobob
May 14th, 2021, 03:29
Nice extension. I did find the conflict that was happening mentioned before with the onDrop error. We both have extensions, Critically Awesome Essentials and Token Height extension, that both add to image_record_step... so, I figured out the deconflict, is you wished to make them work together nicely.

in your /campaign/scripts/image.lua you can add the following script to the bottom of the file.


function onDrop(x, y, draginfo)
local custData = {};
custData.x = x ;
custData.y = y ;
custData.imgCtrl = self ;
if draginfo.getType() == "token" then
draginfo.setCustomData(custData);
end;
end

Additionally I am attaching a copy of your extension with the deconflict installed in it. I also added the version notes and advanced the version to 3.7

V/r,
Diablobob

GKEnialb
May 14th, 2021, 04:24
Thanks! I've incorporated that into v3.7. I also reverted a change to extension.xml, which hopefully will fix other instances of randomly disappearing image functions (see Functions from image.lua disappearing (https://www.fantasygrounds.com/forums/showthread.php?68378-Functions-from-image-lua-disappearing&p=599773#post599773)). Not sure about the faction dropping thing - maybe one of these will fix that for free...

GKEnialb
May 14th, 2021, 04:50
Thanks for the extension! I patched the XML file to include Pathfinder 2 and it seems to work properly.

Diagonal target range calculation confuses me, though. Why is this 10 ft instead of 5 ft?

https://i.imgur.com/v0K3G6C.png

I added PFRPG2 in v3.7. For variant diagonals, I extend the 2D calculation of long leg + 1/2 short leg to be longest leg + 1/2 of both shorter legs. In this case (5x5x5), it's 5 + 10/2 = 10.

Diablobob
May 14th, 2021, 05:08
So for the calculation, are using the a squared + b squared = c squared?... cause it would be easy with height squared + map token distance squared = square of calculated distance

If you want to look into this let me know and I can get you the callouts if you have a tough time finding them...

I was just curious if your method

GKEnialb
May 14th, 2021, 05:25
For raw measurements (House Rule option in 5E, map option in other rulesets), I use the actual distance (sqrt(x^2+y^2+z^2). For the 5E standard, I extend the 2D method by taking the max in each dimension. For the 5E variant / normal diagonals for most other rulesets, I use long leg + half of each shorter leg (again extending the 2D formula). If you want the exact measurements, it's available in the raw distances option in the maps. If you use the default for the rulesets, though, I want to mimic the spirit as much as possible.

GKEnialb
May 16th, 2021, 02:29
With more help from Moon Wizard, this should now work on maps made full screen or sent the the background. v3.8 uploaded.

anathemort
May 16th, 2021, 23:12
GKEnialb this is a slick extension; you've been putting in a ton of work for what probably seemed like a simple idea at the outset! Thanks for this!

I want to also report a minor bug with FGU 4.1 and v3.8 of this extension. With only this extension enabled, I can no longer use the faction helmets to drag a group of tokens from the CT to a map. If I disable this extension, it works fine.

Attached is a gif demonstration as well as the campaign if you need it to help debug.

nephranka
May 17th, 2021, 00:53
Ran into this issue tonight. With this and Batch 9 Spell tokens ext only in a clean 5e build, I can not place spell tokens on a map. It silently fails. Turn off token height and I can place spell tokens. Did not expect that. Any thoughts? I am posting on Batch 9s thread as well. Thanks!

With both on - spell tokens cannot be placed. (screen1)


With token height off - spell tokens can be placed (screen2)

bratch9
May 17th, 2021, 11:58
Ran into this issue tonight. With this and Batch 9 Spell tokens ext only in a clean 5e build, I can not place spell tokens on a map. It silently fails. Turn off token height and I can place spell tokens. Did not expect that. Any thoughts? I am posting on Batch9s thread as well. Thanks!

With both on - spell tokens cannot be placed. (screen1)


With token height off - spell tokens can be placed (screen2)

I've taken a look at the issues and its a missing super call from the 'diablobob' code in 'image.lua', without the 'super.onDrop' you loose things like 'drag all party tokens to map' from the combat tracker.

-pete



-- From diablobob
function onDrop(x, y, draginfo)
if draginfo.getType() == "token" then
local custData = {};
custData.x = x ;
custData.y = y ;
custData.imgCtrl = self ;
draginfo.setCustomData(custData);
end;

if super and super.onDrop then
return super.onDrop(x, y, draginfo);
end
end


And you should probably not double call 'super.onInit' during your 'onInit' function.



function onInit()
if super and super.onInit then
super.onInit()
end

getDistanceBetween_orig = Token.getDistanceBetween
Token.getDistanceBetween = getDistanceBetween
end

nephranka
May 17th, 2021, 13:46
Well, these changes seem simple enough. I am hope they can be folded into the existing code.

GKEnialb
May 17th, 2021, 21:48
Thanks for looking into this. I'll post an update in a few hours. Hopefully this fixes the issues from both nephranka and anathemort

nephranka
May 17th, 2021, 23:19
Thanks for looking into this. I'll post an update in a few hours. Hopefully this fixes the issues from both nephranka and anathemort

Thanks!

nephranka
May 18th, 2021, 01:17
On a side note. I was on the Discord channel for rob2e and Jeremy post this:

Jeremy Putman — 05/15/2021
for example. I changed a single line in the checkForNerbyEnemies function from


if checkMeleeDistanceBetweenTokens(token, sourceToken) == true then
return true;
end

to

if Token.getDistanceBetween(token, sourceToken) <= 5 then
return true;
end

And it seemed to trigger the same way with or without the new height extension on the FG forums, but also took into account that extensions height variable so if they were side by side, buy 10 ft up it didn't trigger the disadvantage.







It worked for sneak attack and I also tried it in the flanking & range ext from kent and it worked there as well. The one that did not work was pack tactics from kent. This is a big deal for those of us that want to use height and range rules. I let Jeremy know it was a great find. I thought I would share it.

GKEnialb
May 18th, 2021, 01:31
Thanks, nephraka - happy to see that. And thanks bratch9, as the proposed fix seems to work great (I was able to drop asset tokens, so should be fine for spell effects, and drop a bunch of tokens with the faction buttons). v3.9 posted accordingly.

nephranka
May 18th, 2021, 02:12
Looks to working for me. Thanks!

anathemort
May 18th, 2021, 05:01
Thanks, nephraka - happy to see that. And thanks bratch9, as the proposed fix seems to work great (I was able to drop asset tokens, so should be fine for spell effects, and drop a bunch of tokens with the faction buttons). v3.9 posted accordingly.

Working for me, too. Thanks for the fast fix!

kevininrussia
May 20th, 2021, 08:28
4E
Token Height version 3.9

In tonight's game when ever somebody moved their token the Host received this error:

[ERROR] Handler error: [string "campaign/scripts/image.lua"]:30: attempt to index global 'Interface' (a nil value)

Not sure what triggered it. I remember opening an image and had players view it then when we went back to the map with their tokens on it, the error started happening. This extension is the only one with an "image.lua"

bmos
May 20th, 2021, 11:06
I think changing:

if getDistanceDiagMult or Interface.getDistanceDiagMult then
to

if getDistanceDiagMult or (Interface and Interface.getDistanceDiagMult) then
should keep this from occuring, but this is almost certainly an extension compatibility issue

Roach
May 20th, 2021, 14:04
I just experienced something odd:
completely new campaign, 5E, no other extension running
added four characters to the CT, opened a random map [with LoS presets], tried to drag the characters from the CT to the map using the green helmet symbol. During the drag, as expected, a greenish square was shown, but when I released the mouse button, the characters stubbornly refused to enter the map....

bmos
May 20th, 2021, 14:18
I just experienced something odd:
completely new campaign, 5E, no other extension running
added four characters to the CT, opened a random map [with LoS presets], tried to drag the characters from the CT to the map using the green helmet symbol. During the drag, as expected, a greenish square was shown, but when I released the mouse button, the characters stubbornly refused to enter the map....Using v3.9? This was just discussed and fixed.

Weissrolf
May 20th, 2021, 15:20
I think my example (screenshot) should measure as 5 ft, not 10 ft, as this is still the first diagonal. I understand there are different options, so I will try them out in PF2.

Kelrugem
May 20th, 2021, 15:45
I think my example (screenshot) should measure as 5 ft, not 10 ft, as this is still the first diagonal. I understand there are different options, so I will try them out in PF2.

That strongly depends on how you approximate the diagonal multiplier. The usual diagonal in 2D has a multiplier given by the square root of 2 (in the Euclidean metric). Many rulesets approximate that by either 1 or 1.5, and then round down to the next multiple of the grid increment

However, in 3D you do not just have one diagonal in a square grid. The screenshot you show is about a "double-diagonal" whose diagonal multiplier is the square root of 3 (in the Euclidean metric), not of 2. You may approximate it in the same way as the square root of 2, but one may argue that one wants to avoid that. GKEnialb's approximation gives an approximation of 2 for the square root of 3

That actually "makes sense" if you approximate square roots by the continued fraction expansion: https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Continued_fracti on_expansion
There is some table a bit downwards of that article, and the first order approximations of the square root of 2 and 3 are 1.5 and 2, respectively, with respect to that approximation :)

If that fits whatever the rulesets say is of course something different; sadly, ruleset developers (I mean Paizo etc.) do rarely explain things mathematically, if they even think mathematical for such things. Often 3D stuff is done very vague in my opinion. If you like the explanation with the continued fraction expansion, then it may be easier to accept such calculations :)

(Though I assume that it is intended that GKEnialb's extension works like this; I may be wrong, I did not test it on my own. I just only looked at your screenshot)

Does it show a range of 5ft. If the flying and standing tokens are directly next to each other? (because then it would be again a square root of 2, just "one diagonal")

Weissrolf
May 20th, 2021, 16:21
Yes, orthogonal sides show 5 ft. only the 3D diagonal shows 10 ft. PF2 rules state: "As with ground-based movement, moving diagonally up or down in 3-D space requires counting every other diagonal as 10 feet."

Going another step diagonally and up increases the calculation to 20 ft. while it should be 15 ft, it's the second diagonal step.

Kelrugem
May 20th, 2021, 16:33
Yes, orthogonal sides show 5 ft. only the 3D diagonal shows 10 ft. PF2 rules state: "As with ground-based movement, moving diagonally up or down in 3-D space requires counting every other diagonal as 10 feet."

depends now whether they want that one accounts the corresponding diagonal move in the 2D plane :D Because the diagonal of your screenshot also has a diagonal move in the projection into the 2d plane (hence, the square root of 3 talk above). But Paizo may not have thought about that you have two different diagonal movements in 3d, so, difficult to say if there are no examples in the PF2 rules clarifying that (are they?)

bmos
May 20th, 2021, 17:15
I think my example (screenshot) should measure as 5 ft, not 10 ft, as this is still the first diagonal. I understand there are different options, so I will try them out in PF2.
As Kelrugem says, there is some level of uncertainty in how the rules are written.
Right now it appears to have been calculated as 5ft diagonal + 5ft altitude.
Moving further away then becomes 15ft diagonal + 5ft altitude.

Have you considered using raw distance?

Weissrolf
May 20th, 2021, 18:05
They are neighboring squares, that is 5 ft. and people can hit each other over the head. Sometimes answers are that simple. :p

Kelrugem
May 20th, 2021, 18:13
They are neighboring squares, that is 5 ft. and people can hit each other over the head. Sometimes answers are that simple. :p

Also depends :D A flying target is often more difficult to hit, even if adjacent; in the case of your screenshot only the feet and legs may be similar to hit as non-flying targets, while the remaining body becomes more difficult to hit, reducing the probability for a successful attack :D With respect to Euclidean measures the distance from centre to centre is certainly bigger than if the target would not fly :D

kevininrussia
May 20th, 2021, 18:22
I think changing:

if getDistanceDiagMult or Interface.getDistanceDiagMult then
to

if getDistanceDiagMult or (Interface and Interface.getDistanceDiagMult) then
should keep this from occuring, but this is almost certainly an extension compatibility issue

I changed line 30 as you suggested. Will report back after next game if the error happens.
Thanks!

Weissrolf
May 20th, 2021, 18:31
For sake of the game system adjacent squares are 5 ft. apart from each other, in PF2 even the second diagonal is considered 10 ft for the sake of (only) weapon reach. Physics and anatomy are ignored.

It also makes no sense to split a diagonal 3D distance into a 2D diagonal + altitude while drawing orthogonal 3D diagonal distances directly. And at least in PF2 the first 3D diagonal is 5 ft. regardless of direction, just like in 2D. I quoted the CRB rule earlier (page 478).

I will take a look at the code and try to fix it for our PF2 group. It's a useful addon in any case.

Kelrugem
May 20th, 2021, 18:34
For sake of the game system adjacent squares are 5 ft. apart from each other. Physics and anatomy are ignored. It also makes no sense to split a diagonal 3D distance into a 2D diagonal + altitude while drawing orthogonal 3D diagonal distances directly. And at least in PF2 the first 3D diagonal is 5 ft. regardless of direction, just like in 2D. I quoted the CRB rule earlier (page 478).

No reason to become blunt :) My last answer was actually partially also a joke since I found the imagination behind that situation funny

And you misunderstood, it is essentially not split like that (though may be equivalent to that after an approximation); see my explanation above. Not every diagonal in 3d is the same, and I can understand if GKEnialb wanted to cater for that. That is just something purely mathematical, no anatomy, no physics. However, maybe GKEnialb will add an option for that, maybe not; and as also bmos said, your quote still contains some degree of uncertainty

Weissrolf
May 20th, 2021, 18:36
I added another quote for more clarity, but that was after your next post. You are too fast for me. :p

"Measure flanking in all directions— creatures above and below an enemy can flank it just as effectively as they can from opposite sides."

Kelrugem
May 20th, 2021, 18:37
I added another quote for more clarity, but that was after your next post. You are too fast for me. :p

"Measure flanking in all directions— creatures above and below an enemy can flank it just as effectively as they can from opposite sides."

aah, oki, indeed, PF2 seems to do as you propose :)

GKEnialb
May 21st, 2021, 05:01
4E
Token Height version 3.9

In tonight's game when ever somebody moved their token the Host received this error:

[ERROR] Handler error: [string "campaign/scripts/image.lua"]:30: attempt to index global 'Interface' (a nil value)

Not sure what triggered it. I remember opening an image and had players view it then when we went back to the map with their tokens on it, the error started happening. This extension is the only one with an "image.lua"

Uploaded v3.10 to protect against this error (though as with the other "disappearing" functions, no guarantee as to the behavior if this comes up - at least it'll stop the error in the console). Thanks for the response, bmos.


I just experienced something odd:
completely new campaign, 5E, no other extension running
added four characters to the CT, opened a random map [with LoS presets], tried to drag the characters from the CT to the map using the green helmet symbol. During the drag, as expected, a greenish square was shown, but when I released the mouse button, the characters stubbornly refused to enter the map....

Any drop issues should have been fixed in v3.9. I tried to recreate it, but couldn't. Which random map was it? If I have it as well, I can take a look at the grid settings.


I think my example (screenshot) should measure as 5 ft, not 10 ft, as this is still the first diagonal. I understand there are different options, so I will try them out in PF2.
Still trying to get my head around this not being considered two diagonals. Granted, if it is, then according to the rules you quoted, it'd be 15 ft and not 10 ft, so my formula wouldn't work either way... I can definitely either have a different formula for PFRPG2 or put an option in (would prefer to do the former, as I'd have to add an option to the existing set of options for 5E and create new options for non-5E) - just need to contemplate what that formula would be (which will probably hit me about the time as I can imagine the cubes touching on one vertex is considered the same as two cubes touching on an edge which is considered the same as two cubes touching on their faces). :)

GKEnialb
May 21st, 2021, 18:07
Okay, v4.0 is now posted, which gives a different diagonal distance than the other 5/15 diagonal variants. Weissrolf, let me know if this meets what you were hoping for. The only difference really turns out to be when all the deltas are the same: a 5'x5'x5' delta in this will be 5' as requested (and 10'x10'x10' will be 15') as opposed to 10' and 20' with the other. If anybody preferred the original formula in PFRPG2 or wants this new behavior in another ruleset, let me know and I'll add an option to toggle between the two.

Roach
May 22nd, 2021, 15:05
Using v3.9? This was just discussed and fixed.

Mea culpa - I hadn`t realized it had been updated, relying on MNM's 3rd Party Updater.

GKEnialb
May 22nd, 2021, 17:44
Mea culpa - I hadn`t realized it had been updated, relying on MNM's 3rd Party Updater.

No worries - didn't even know about that extension. Looks very useful, so I've submitted the form to add this extension to Mad Nomad's list.

kevininrussia
May 24th, 2021, 00:47
Got this error today after Shift Drag a token to a new location on the same map. After I did the Shift Drag this error happened then every time that token was moved the error happened.

https://i.imgur.com/Ng1w4YA.png

Khoredran
May 24th, 2021, 00:57
Oh! That's exactly the same error I got! If this error is linked to this extension that would be helpful to be corrected!
I thought it was an interraction with the Aura extension.

GKEnialb
May 24th, 2021, 01:12
We have to figure out why all of these functions keep disappearing. It is a call made from this extension, but CombatManager isn't modified in my extension. Can you give me details on your setup (other extensions, ruleset, etc?) and can you reproduce it? I can put guards around the call to prevent an error, but you can't really do much if the CombatManager goes away. Thanks.

kevininrussia
May 24th, 2021, 01:36
We have to figure out why all of these functions keep disappearing. It is a call made from this extension, but CombatManager isn't modified in my extension. Can you give me details on your setup (other extensions, ruleset, etc?) and can you reproduce it? I can put guards around the call to prevent an error, but you can't really do much if the CombatManager goes away. Thanks.

I exited FGU and reloaded to see if I could duplicate the error but was unsuccessful.

Ruleset is 4e.
I have a bunch of extensions including Aura Effects.

I will mess around later with trying to recreate the error by adding extensions one at a time.

GKEnialb
May 24th, 2021, 02:05
Thanks - appreciate the effort.

bmos
May 24th, 2021, 11:24
I've got another one for you :|
https://github.com/bmos/FG-Aura-Effect/issues/10

I wonder what is going on with these!
Perhaps see if everyone having that issue is also using Aura Effect?

Khoredran
May 24th, 2021, 14:01
I couldn't recreate locally since I can't recreate the exact conditions of the error 48. It happened during a live cloud game with four players connected. A neutral NPC with an AURA effect was introduced to the game at the beginning of the session and the error started when trying to move any character loaded in the CT and/or added later or even after PCs were changed of map or moved via Shift Drag. It really was a "close spammed logs every single token move" festival for 4 hours, but I kept quiet. No player saw the log error and I ignored it because you know, the show must go on. ^^

When moving the party token that was not linked to the CT in the Overland Map with no AURA active in that map, no error was encountered.

This is with the PFRPG1 Ruleset with these extensions:
FG-CoreRPG-Coins-Weight
FG-CoreRPG-Extraplanar-Containers
FG-PFRPG-Ammunition-Manager
FG-PFRPG-Encumbrance-Penalties
FG-PFRPG-Malady-Tracker
FG-PFRPG-NaturalArmorBonusTypes
FG-PFRPG-Time-Manager
MirrorImageHandler
Mythic-Abilities
PFRemoveEffectTag
TokenHeight
WindowSaver
Drain-and-Permanent-Bonuses
FG-PFRPG-Extra-Stat-to-Saves
FG-PFRPG-Spell-Formatting
FullOverlayPackagewithalternativeicons
FG-PFRPG-Advanced-Effects
PFRPG-EnhancedItems
FG-PFRPG-Advanced-Character-Inventory-Manager
FG-PFRPG-Live-Hitpoints
FG-PFRPG-Item-Durability
BetterMenus
FG-Aura-Effect

nephranka
May 24th, 2021, 14:15
I couldn't recreate locally since I can't recreate the exact conditions of the error 48. It happened during a live cloud game with four players connected. A neutral NPC with an AURA effect was introduced to the game at the beginning of the session and the error started when trying to move any character loaded in the CT and/or added later or even after PCs were changed of map or moved via Shift Drag. It really was a "close spammed logs every single token move" festival for 4 hours, but I kept quiet. No player saw the log error and I ignored it because you know, the show must go on. ^^

When moving the party token that was not linked to the CT in the Overland Map with no AURA active in that map, no error was encountered.

Very similar experience for me as well. The only difference was a foe npc not visible was added to the CT and the errors started. Not reproducible, so far, but I will keep at it.

rhagelstrom
May 24th, 2021, 16:49
I've got another one for you :|
https://github.com/bmos/FG-Aura-Effect/issues/10

I wonder what is going on with these!
Perhaps see if everyone having that issue is also using Aura Effect?

The two different times this happened to me, two different campaigns. I was using Aura Effect as well as Height. It also happened an hour to hour and a half into the sessions both times.

kevininrussia
May 24th, 2021, 18:09
I'll see if I get the error again with only Aura Effect loaded and not Height in our next game.

The error only happens on the GM host side, players don't see it. I had to deal with the console up every time a player moved their token for about an hour till the end of our game... as was stated earlier, the show must go on :-)

Hopefully the conflict will get worked out as Height is a really awesome extension.

mattekure
May 24th, 2021, 18:33
I just finished some tweaking/testing on the CoreRPG Coins extension, and began receiving a very similar error. I found that all of the functions were declared as local functions, which is not what I am used to doing. So I tried changing them all from the format:

local function abc()

to

function abc()

After doing this I stopped having that error. I cant say 100% for sure this is the cause for what others are experiencing, but it may be involved somehow.

bmos
May 24th, 2021, 18:38
I just finished some tweaking/testing on the CoreRPG Coins extension, and began receiving a very similar error. I found that all of the functions were declared as local functions, which is not what I am used to doing. So I tried changing them all from the format:

local function abc()

to

function abc()

After doing this I stopped having that error. I cant say 100% for sure this is the cause for what others are experiencing, but it may be involved somehow.Actually not all of them, just the ones that only needed to be called from within that script. Using local functions is a good idea when they aren't going to be needed in another scope, but perhaps this does not work in certain circumstances such as when also using function replacement in another script (such as Token.getDistanceBetween = getDistanceBetween) or perhaps when using OOB. I've been doing the former for a while without seeing this issue, but I only just started using OOB recently so it could be that. I have globalized the functions involved in OOB messaging (but not the other local functions) for Auras v1.1-beta.2. If someone who is having this issue can give it a shot I'd love to hear your results.

EDIT: looks like I had a couple typos. here is a working test build: Auras v1.1-beta.3 (https://github.com/bmos/FG-Aura-Effect/releases/tag/v1.1-beta.3)

Khoredran
May 25th, 2021, 00:29
I tried the Aura v.1.1-beta.2. with all my other extensions and the AURAs in the CT just stopped working altogether.
I also tried the extension alone in a new TEST campaign and no success either. Ruleset used: PFRPG1

EDIT: I tried the Aura v.1.1-beta.3 with all the extensions and everything seems to be working as intended!
I will have to try it in a live play with all the players connected, but this looks promising. ^^

GKEnialb
May 26th, 2021, 01:52
Interesting! I have a local function as well (or did - just uploaded v4.1 which changes that).

Weissrolf
May 31st, 2021, 02:23
Thanks for the PF2 changes, well appreciated! Our group will start using the extension actively now and report if anything odd happens.

GKEnialb
May 31st, 2021, 03:43
No worries. Hopefully all will work well for your group.

Weissrolf
May 31st, 2021, 08:35
Suggestion: Allow modifier keys (shift / ctrl) to be held to change target distance display as difficult terrain = against the wind or upwards (each square costs an extra 5") or greater difficult terrain = against the wind and upwards (each square costs an extra 10").

If possible, maybe even calculate locked movement distance? When a character has a movement path locked in and then changes height on his token the movement distance display could be altered accordingly (always calculating the old height as relative basis).

Weissrolf
May 31st, 2021, 10:01
One problem: with the extension enabled the mouse-wheel does not zoom the map anymore when the mouse hovers over a token with no modifier key pressed.

Drogo210
May 31st, 2021, 16:42
When this extension is loaded (even alone), it does not allow you to drop NPC/PC, as a group, from the combat tracker by using the bottom buttons (Friendly/Neutral Hostile)

GKEnialb
May 31st, 2021, 17:06
When this extension is loaded (even alone), it does not allow you to drop NPC/PC, as a group, from the combat tracker by using the bottom buttons (Friendly/Neutral Hostile)

Can you confirm you have the latest version? That was fixed a few builds ago. If you do have the latest, let me know the ruleset you're using and what version of FGU you have running.


One problem: with the extension enabled the mouse-wheel does not zoom the map anymore when the mouse hovers over a token with no modifier key pressed.
Yeah, if I pass it through to the base function when no modifier is set, it resizes the token. I could copy the base function for map resizing, but that hurts the maintenance of the extension and increases conflicts with others.

Drogo210
May 31st, 2021, 17:26
Can you confirm you have the latest version? That was fixed a few builds ago. If you do have the latest, let me know the ruleset you're using and what version of FGU you have running.

No, I had the previous one, 5e_Mad Nomad's 3rd Party Updater did not say...where are Mad when we need you :). Now works

GKEnialb
May 31st, 2021, 17:32
No, I had the previous one, 5e_Mad Nomad's 3rd Party Updater did not say...where are Mad when we need you :). Now works

No worries. I did submit the info on the extension to the updater, so hopefully it gets added soon. :)

GKEnialb
June 1st, 2021, 01:13
Suggestion: Allow modifier keys (shift / ctrl) to be held to change target distance display as difficult terrain = against the wind or upwards (each square costs an extra 5") or greater difficult terrain = against the wind and upwards (each square costs an extra 10").

If possible, maybe even calculate locked movement distance? When a character has a movement path locked in and then changes height on his token the movement distance display could be altered accordingly (always calculating the old height as relative basis).

Thanks for the suggestions. I'll contemplate those for the future - want to make sure everything is nice and stable for a bit before adding new functionality.