-
March 25th, 2021, 03:56 #1
Can the range calculation be overridden?
I created an extension to allow height the height of tokens to be set https://www.fantasygrounds.com/forum...ight-Indicator and somebody asked if I could update the range arrow with a distance taking height into account. The distance calculations are straight-forward enough, but I can't find a way to either update the text displayed on the range arrow or modify the underlying range calculation (and let the arrow just use that). Is it possible to do either? I see there's an Interface function to setDistanceDiagMult, which isn't listed in the Interface package API, so I was hoping there was some other undocumented API with more distance controls (or any other method).
-
March 25th, 2021, 13:21 #2
- Join Date
- Sep 2018
- Posts
- 75
https://fantasygroundsunity.atlassia...MeasurePointer
That lets you define the lable of the measure pointer.
-
March 26th, 2021, 01:10 #3
-
March 31st, 2021, 02:19 #4
I was able to do this after getting info from several threads, so figured I'd put what I found here so it's consolidated (and to see if I got anything wrong ).
- onMeasurePointer is found in campaign/scipts/image.lua (from CoreRPG) - it's not actually in the CoreRPG version, so it needs to be appended
- You have to override everything in image.lua and the original functions aren't available to call (so can't just override a portion and call the original for the rest) -- actually, see the post below
- image.lua has to called out in your xml file as below (including being inside of <base>)
Code:<base> <template name="image_record_step"> <imagecontrol name="image"> <indicators locked="image_locked" loading="image_loading" /> <default snap="on" drawingsize="500,500" /> <script file="campaign/scripts/image.lua" /> </imagecontrol> </template> </base>
- You can't just override the targeting arrows; the same logic is used for the pointers as well
- I had to look at the endpoint of the arrow to see what token it was pointing to (so I could get its height). Comparing that endpoint to the position of a tiny/small/medium creature worked just fine; for a large or huge creature, I had to adjust their position by half a gridsize and a full gridsize, respectively; gargantuan creatures are a little wacky - I had to just check if the endpoint was within 1.5 gridsizes (as opposed to being exactly 1.5 gridsizes off)
This is the code I wrote for the actual distance calculations is as follows (and doesn't quite work for "variant" coming from a corner)
Code:function distanceBetween(startx,starty,startz,endx,endy,endz) local diagMult = Interface.getDistanceDiagMult() local units = getDistanceBaseUnits() local gridsize = getGridSize() local totalDistance = 0 local dx = math.abs(endx-startx) local dy = math.abs(endy-starty) local dz = math.abs(endz-startz) 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 longest = math.max(dx, dy, dz) if longest == dx then totalDistance = dx + (dy+dz)/2 elseif longest == dy then totalDistance = dy + (dx+dz)/2 else totalDistance = dz + (dx+dy)/2 end -- Convert to feet totalDistance = (totalDistance / gridsize + 0.5) * units totalDistance = math.floor(totalDistance / units) * units end return totalDistance end
Last edited by GKEnialb; March 31st, 2021 at 02:51.
-
March 31st, 2021, 02:27 #5
Supreme Deity
- Join Date
- Mar 2007
- Posts
- 20,554
I believe you can override a control's script using a windowclass merge.
Example:
Code:<windowclass name="imagewindow" merge="join"> <sheetdata> <image_record name="image"> <script file="campaign/scripts/image_overrides.lua" /> </image_record> </sheetdata> </windowclass>
Regards,
JPG
-
March 31st, 2021, 02:32 #6
Awesome - that will be a lot less maintenance!
And confirmed that you're correct; I was able to use the merge and remove all of the base functions.Last edited by GKEnialb; March 31st, 2021 at 02:44.
-
April 2nd, 2021, 02:47 #7
To expand on the figuring out the target, I couldn't find a method to determine which target the arrow was pointing to, so I made this general function.
Code:function getCTNodeAt(basex, basey, gridsize) local allTokens = getTokens() local theToken = nil for _, oneToken in pairs(allTokens) do x,y = oneToken.getPosition() local ctNode = CombatManager.getCTFromToken(oneToken) local sSize = StringManager.trim(DB.getValue(ctNode, "size", ""):lower()); local bExact = true local sizeMultiplier = 0 if sSize == "large" then sizeMultiplier = 0.5 elseif sSize == "huge" then sizeMultiplier = 1 elseif sSize == "gargantuan" then -- Gargantuan creatures behave a bit differently. Can be anywhere within bounds sizeMultiplier = 1.5 bExact = false end local found = false if bExact then found = exactMatch(basex, basey, x, y, sizeMultiplier, gridsize) else found = matchWithinSize(basex, basey, x, y, sizeMultiplier, gridsize) end if found then local ctNode = CombatManager.getCTFromToken(oneToken) theToken = ctNode break end end return theToken end
Code: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
Code: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
-
April 2nd, 2021, 22:44 #8
And just one more (hopefully) question - is there a way to force a redraw of the targeting arrow programmatically? If I change my height on a token, I have to move the pointer until it loses focus and return it to gain focus to get the onMeasurePointer to activate.
-
April 3rd, 2021, 18:01 #9
Supreme Deity
- Join Date
- Mar 2007
- Posts
- 20,554
No, the onMeasurePointer function is only called when the the targeting line changes.
Regards,
JPG
-
April 3rd, 2021, 18:12 #10
Thanks for the confirmation - the workaround isn't that bad. Do you know of an easier way of determining what's at the other end of the arrow within onMeasurePointer than looking up each token's position as I have above?
Thread Information
Users Browsing this Thread
There are currently 1 users browsing this thread. (0 members and 1 guests)
Bookmarks